Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
HumanReadableConverter.cs
浏览该文件的文档.
1using System.Diagnostics.CodeAnalysis;
2using System.Reflection;
3
4namespace Engine.Serialization {
5 public static class HumanReadableConverter {
6 static Dictionary<Type, IHumanReadableConverter> m_humanReadableConvertersByType = [];
7
8 static HashSet<Assembly> m_scannedAssemblies = [];
9
10 public static string ConvertToString(object value) {
11 if (value == null) {
12 return string.Empty;
13 }
14 Type type = value.GetType();
15 Type nullableUnderlyingType = Nullable.GetUnderlyingType(type);
16 try {
17 return nullableUnderlyingType == null
18 ? GetConverter(type, true).ConvertToString(value)
19 : GetConverter(nullableUnderlyingType, true).ConvertToString(value);
20 }
21 catch (Exception innerException) {
22 throw new InvalidOperationException($"Cannot convert value of type \"{type.FullName}\" to string.", innerException);
23 }
24 }
25
26 public static bool TryConvertFromString(Type type, string data, out object result) {
27 try {
28 Type nullableUnderlyingType = Nullable.GetUnderlyingType(type);
29 if (nullableUnderlyingType == null) {
30 result = GetConverter(type, true).ConvertFromString(type, data);
31 return true;
32 }
33 if (string.IsNullOrEmpty(data)) {
34 result = null;
35 return true;
36 }
37 result = GetConverter(nullableUnderlyingType, true).ConvertFromString(nullableUnderlyingType, data);
38 return true;
39 }
40 catch (Exception) {
41 result = null;
42 return false;
43 }
44 }
45
46 public static bool TryConvertFromString<T>(string data, out T result) {
47 if (TryConvertFromString(typeof(T), data, out object result2)) {
48 result = (T)result2;
49 return true;
50 }
51 result = default;
52 return false;
53 }
54
55 public static object ConvertFromString(Type type, string data) {
56 try {
57 Type nullableUnderlyingType = Nullable.GetUnderlyingType(type);
58 return nullableUnderlyingType == null ? GetConverter(type, true).ConvertFromString(type, data) :
59 string.IsNullOrEmpty(data) ? null : GetConverter(nullableUnderlyingType, true).ConvertFromString(nullableUnderlyingType, data);
60 }
61 catch (Exception innerException) {
62 throw new InvalidOperationException($"Cannot convert string \"{data}\" to value of type \"{type.FullName}\".", innerException);
63 }
64 }
65
66 public static T ConvertFromString<T>(string data) => (T)ConvertFromString(typeof(T), data);
67
68 public static bool IsTypeSupported(Type type) => GetConverter(type, false) != null;
69
70 public static string ValuesListToString<T>(char separator, params T[] values) {
71 string[] array = new string[values.Length];
72 for (int i = 0; i < values.Length; i++) {
73 array[i] = ConvertToString(values[i]);
74 }
75 return string.Join(separator.ToString(), array);
76 }
77
78 public static T[] ValuesListFromString<T>(char separator, string data) {
79 if (!string.IsNullOrEmpty(data)) {
80#if ANDROID
81 string[] array = data.Split([separator], StringSplitOptions.None);
82#else
83 string[] array = data.Split(separator);
84#endif
85 T[] array2 = new T[array.Length];
86 for (int i = 0; i < array.Length; i++) {
87 array2[i] = ConvertFromString<T>(array[i]);
88 }
89 return array2;
90 }
91 return [];
92 }
93
94 static IHumanReadableConverter GetConverter(Type type, bool throwIfNotFound) {
95 ArgumentNullException.ThrowIfNull(type);
97 if (!m_humanReadableConvertersByType.TryGetValue(type, out IHumanReadableConverter value)) {
99 if (!m_humanReadableConvertersByType.TryGetValue(type, out value)) {
100 foreach (KeyValuePair<Type, IHumanReadableConverter> item in m_humanReadableConvertersByType) {
101 if (type.GetTypeInfo().IsSubclassOf(item.Key)) {
102 value = item.Value;
103 break;
104 }
105 }
106 m_humanReadableConvertersByType.Add(type, value);
107 }
108 }
109 return value
110 ?? (throwIfNotFound
111 ? throw new InvalidOperationException(
112 $"IHumanReadableConverter for type \"{type.FullName}\" not found in any loaded assembly."
113 )
114 : null);
115 }
116 }
117
119 foreach (Assembly item in TypeCache.LoadedAssemblies.Where(a => !TypeCache.IsKnownSystemAssembly(a))) {
120 if (!m_scannedAssemblies.Contains(item)) {
121#pragma warning disable IL2026
122 foreach (TypeInfo definedType in item.DefinedTypes) {
123#pragma warning restore IL2026
124 HumanReadableConverterAttribute customAttribute = definedType.GetCustomAttribute<HumanReadableConverterAttribute>();
125 if (customAttribute != null) {
126 Type[] types = customAttribute.Types;
127 foreach (Type key in types) {
128 if (!m_humanReadableConvertersByType.ContainsKey(key)) {
129#pragma warning disable IL2072
130 IHumanReadableConverter value = (IHumanReadableConverter)Activator.CreateInstance(definedType.AsType());
131#pragma warning restore IL2072
132 m_humanReadableConvertersByType.Add(key, value);
133 }
134 }
135 }
136 }
137 m_scannedAssemblies.Add(item);
138 }
139 }
140 }
141 }
142}
static bool TryConvertFromString< T >(string data, out T result)
static string ValuesListToString< T >(char separator, params T[] values)
static Dictionary< Type, IHumanReadableConverter > m_humanReadableConvertersByType
static bool TryConvertFromString(Type type, string data, out object result)
static T[] ValuesListFromString< T >(char separator, string data)
static IHumanReadableConverter GetConverter(Type type, bool throwIfNotFound)
static object ConvertFromString(Type type, string data)
static bool IsKnownSystemAssembly(Assembly assembly)
static ReadOnlyList< Assembly > LoadedAssemblies
object ConvertFromString(Type type, string data)