wasSharp – Blame information for rev 52
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
2 | zed | 1 | /////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
||
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
||
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
||
5 | /////////////////////////////////////////////////////////////////////////// |
||
6 | |||
7 | using System; |
||
8 | using System.Collections.Generic; |
||
9 | using System.Linq; |
||
10 | using System.Reflection; |
||
11 | |||
12 | namespace wasSharp |
||
13 | { |
||
7 | office | 14 | public static class Reflection |
2 | zed | 15 | { |
16 | /////////////////////////////////////////////////////////////////////////// |
||
17 | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // |
||
18 | /////////////////////////////////////////////////////////////////////////// |
||
19 | /// <summary> |
||
20 | /// Retrieves an attribute of type T from an enumeration. |
||
21 | /// </summary> |
||
22 | /// <returns>an attribute of type T</returns> |
||
5 | eva | 23 | public static T GetAttributeFromEnumValue<T>(Enum value) where T : Attribute |
2 | zed | 24 | { |
27 | office | 25 | return (T)value.GetType() |
2 | zed | 26 | .GetRuntimeField(value.ToString()) |
10 | office | 27 | .GetCustomAttributes(typeof(T), false) |
2 | zed | 28 | .SingleOrDefault(); |
29 | } |
||
30 | |||
31 | /////////////////////////////////////////////////////////////////////////// |
||
32 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
||
33 | /////////////////////////////////////////////////////////////////////////// |
||
34 | /// <summary> |
||
35 | /// Returns all the attributes of type T of an enumeration. |
||
36 | /// </summary> |
||
37 | /// <typeparam name="T">the attribute to retrieve</typeparam> |
||
38 | /// <returns>a list of attributes</returns> |
||
5 | eva | 39 | public static IEnumerable<T> GetEnumAttributes<T>(Enum e) where T : Attribute |
2 | zed | 40 | { |
7 | office | 41 | return e.GetType().GetRuntimeFields().ToArray() |
3 | eva | 42 | .AsParallel() |
27 | office | 43 | .Select(o => GetAttributeFromEnumValue<T>((Enum)o.GetValue(Activator.CreateInstance<T>()))); |
2 | zed | 44 | } |
45 | |||
46 | /////////////////////////////////////////////////////////////////////////// |
||
47 | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // |
||
48 | /////////////////////////////////////////////////////////////////////////// |
||
49 | /// <summary> |
||
50 | /// Returns all the field names of an enumeration. |
||
51 | /// </summary> |
||
52 | /// <returns>the field names</returns> |
||
5 | eva | 53 | public static IEnumerable<string> GetEnumNames<T>() |
2 | zed | 54 | { |
55 | return |
||
10 | office | 56 | typeof(T).GetRuntimeFields().ToArray() |
2 | zed | 57 | .AsParallel() |
10 | office | 58 | .Select(o => o.GetCustomAttribute(typeof(NameAttribute), false)) |
2 | zed | 59 | .Select(o => (o as NameAttribute)?.Name) |
60 | .Where(o => !string.IsNullOrEmpty(o)) |
||
61 | .Select(o => o); |
||
62 | } |
||
63 | |||
64 | /////////////////////////////////////////////////////////////////////////// |
||
65 | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // |
||
66 | /////////////////////////////////////////////////////////////////////////// |
||
67 | /// <summary> |
||
68 | /// Returns all the values of an enumeration. |
||
69 | /// </summary> |
||
70 | /// <returns>the values of the enumeration</returns> |
||
5 | eva | 71 | public static IEnumerable<T> GetEnumValues<T>() |
2 | zed | 72 | { |
27 | office | 73 | return Enum.GetValues(typeof(T)).Cast<object>().Select(value => (T)value); |
2 | zed | 74 | } |
75 | |||
76 | /////////////////////////////////////////////////////////////////////////// |
||
77 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
||
78 | /////////////////////////////////////////////////////////////////////////// |
||
79 | /// <summary> |
||
7 | office | 80 | /// Get the name from an enumeration value. |
2 | zed | 81 | /// </summary> |
82 | /// <param name="value">an enumeration value</param> |
||
83 | /// <returns>the description or the empty string</returns> |
||
5 | eva | 84 | public static string GetNameFromEnumValue(Enum value) |
2 | zed | 85 | { |
7 | office | 86 | var attribute = value.GetType() |
2 | zed | 87 | .GetRuntimeField(value.ToString()) |
10 | office | 88 | .GetCustomAttributes(typeof(NameAttribute), false) |
2 | zed | 89 | .SingleOrDefault() as NameAttribute; |
90 | return attribute?.Name; |
||
91 | } |
||
92 | |||
93 | /////////////////////////////////////////////////////////////////////////// |
||
94 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
||
95 | /////////////////////////////////////////////////////////////////////////// |
||
96 | /// <summary> |
||
97 | /// Get the description from an enumeration value. |
||
98 | /// </summary> |
||
99 | /// <param name="value">an enumeration value</param> |
||
100 | /// <returns>the description or the empty string</returns> |
||
5 | eva | 101 | public static string GetDescriptionFromEnumValue(Enum value) |
2 | zed | 102 | { |
7 | office | 103 | var attribute = value.GetType() |
2 | zed | 104 | .GetRuntimeField(value.ToString()) |
10 | office | 105 | .GetCustomAttributes(typeof(DescriptionAttribute), false) |
2 | zed | 106 | .SingleOrDefault() as DescriptionAttribute; |
107 | return attribute?.Description; |
||
108 | } |
||
109 | |||
110 | /////////////////////////////////////////////////////////////////////////// |
||
111 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
||
112 | /////////////////////////////////////////////////////////////////////////// |
||
113 | /// <summary> |
||
114 | /// Get enumeration value from its name attribute. |
||
115 | /// </summary> |
||
116 | /// <typeparam name="T">the enumeration type</typeparam> |
||
117 | /// <param name="name">the description of a member</param> |
||
21 | office | 118 | /// <param name="comparison">the string comparison to use</param> |
2 | zed | 119 | /// <returns>the value or the default of T if case no name attribute found</returns> |
24 | office | 120 | public static T GetEnumValueFromName<T>(string name, |
121 | StringComparison comparison = StringComparison.OrdinalIgnoreCase) |
||
2 | zed | 122 | { |
10 | office | 123 | var field = typeof(T).GetRuntimeFields().ToArray() |
2 | zed | 124 | .AsParallel().SelectMany(f => f.GetCustomAttributes( |
10 | office | 125 | typeof(NameAttribute), false), ( |
27 | office | 126 | f, a) => new { Field = f, Att = a }) |
127 | .SingleOrDefault(a => string.Equals(((NameAttribute)a.Att) |
||
21 | office | 128 | .Name, name, comparison)); |
27 | office | 129 | return field != null ? (T)field.Field.GetValue(Activator.CreateInstance<T>()) : default(T); |
2 | zed | 130 | } |
131 | |||
132 | /////////////////////////////////////////////////////////////////////////// |
||
133 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
||
134 | /////////////////////////////////////////////////////////////////////////// |
||
135 | /// <summary> |
||
7 | office | 136 | /// Get the name of a structure member. |
2 | zed | 137 | /// </summary> |
138 | /// <typeparam name="T">the type of the structure to search</typeparam> |
||
139 | /// <param name="structure">the structure to search</param> |
||
140 | /// <param name="item">the value of the item to search</param> |
||
141 | /// <returns>the description or the empty string</returns> |
||
5 | eva | 142 | public static string GetStructureMemberName<T>(T structure, object item) where T : struct |
2 | zed | 143 | { |
35 | office | 144 | var f = typeof(T).GetRuntimeFields(); |
145 | var p = typeof(T).GetRuntimeProperties(); |
||
146 | |||
147 | if (f != null) |
||
37 | office | 148 | { |
149 | var r = f.AsParallel() |
||
35 | office | 150 | .SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false), |
151 | (o, a) => new { Field = o, Att = a }) |
||
152 | .SingleOrDefault(q => q.Field.GetValue(structure).Equals(item)); |
||
37 | office | 153 | if (r != null) |
154 | return ((NameAttribute)r.Att).Name; |
||
155 | } |
||
35 | office | 156 | |
157 | if (p != null) |
||
37 | office | 158 | { |
159 | var r = p.AsParallel() |
||
35 | office | 160 | .SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false), |
161 | (o, a) => new { Property = o, Att = a }) |
||
162 | .SingleOrDefault(q => q.Property.GetValue(structure).Equals(item)); |
||
37 | office | 163 | if (r != null) |
164 | return ((NameAttribute)r.Att).Name; |
||
165 | } |
||
35 | office | 166 | |
37 | office | 167 | return string.Empty; |
2 | zed | 168 | } |
3 | eva | 169 | |
7 | office | 170 | /////////////////////////////////////////////////////////////////////////// |
171 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
||
172 | /////////////////////////////////////////////////////////////////////////// |
||
3 | eva | 173 | /// <summary> |
7 | office | 174 | /// Get field or property from a class by supplying a path. |
175 | /// </summary> |
||
176 | /// <typeparam name="T">the type of the object</typeparam> |
||
177 | /// <param name="o">the object</param> |
||
178 | /// <param name="path">the fully qualified path to the field of property</param> |
||
179 | /// <returns> |
||
180 | /// the last object in the fully qualified path or null in case the field or property could not be found |
||
181 | /// </returns> |
||
182 | public static object GetFP<T>(this T o, string path) |
||
183 | { |
||
184 | if (string.IsNullOrEmpty(path)) return null; |
||
185 | if (o == null) return null; |
||
186 | |||
187 | var memberType = o.GetType(); |
||
188 | var components = path.Split('.'); |
||
189 | |||
190 | var f = memberType.GetRuntimeField(components[0]); |
||
191 | var p = memberType.GetRuntimeProperty(components[0]); |
||
192 | |||
193 | if (f != null) |
||
194 | return components.Length > 1 |
||
195 | ? GetFP(f.GetValue(o), |
||
196 | components.Skip(1).Aggregate((a, i) => a + @"." + i)) |
||
197 | : memberType.GetRuntimeField(path).GetValue(o); |
||
198 | |||
199 | if (p != null) |
||
200 | return components.Length > 1 |
||
201 | ? GetFP(p.GetValue(o), |
||
202 | components.Skip(1).Aggregate((a, i) => a + @"." + i)) |
||
203 | : memberType.GetRuntimeProperty(path).GetValue(o); |
||
204 | |||
205 | return null; |
||
206 | } |
||
207 | |||
208 | /////////////////////////////////////////////////////////////////////////// |
||
209 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
||
210 | /////////////////////////////////////////////////////////////////////////// |
||
211 | /// <summary> |
||
212 | /// Get field or property info from a class by supplying a path. |
||
213 | /// </summary> |
||
214 | /// <typeparam name="T">the type of the object</typeparam> |
||
215 | /// <param name="o">the object</param> |
||
216 | /// <param name="path">the fully qualified path to the field of property</param> |
||
217 | /// <returns> |
||
218 | /// the field or property info of the last object in the path or null if the object cannot be found |
||
219 | /// </returns> |
||
220 | public static object GetFPInfo<T>(this T o, string path) |
||
221 | { |
||
222 | if (string.IsNullOrEmpty(path)) return null; |
||
223 | if (o == null) return null; |
||
224 | |||
225 | var memberType = o.GetType(); |
||
226 | var components = path.Split('.'); |
||
227 | |||
228 | var f = memberType.GetRuntimeField(components[0]); |
||
229 | var p = memberType.GetRuntimeProperty(components[0]); |
||
230 | |||
231 | if (f != null) |
||
232 | return components.Length > 1 |
||
233 | ? GetFPInfo(f.GetValue(o), |
||
234 | components.Skip(1).Aggregate((a, i) => a + @"." + i)) |
||
235 | : memberType.GetRuntimeField(path); |
||
236 | |||
237 | if (p != null) |
||
238 | return components.Length > 1 |
||
239 | ? GetFPInfo(p.GetValue(o), |
||
240 | components.Skip(1).Aggregate((a, i) => a + @"." + i)) |
||
241 | : memberType.GetRuntimeProperty(path); |
||
242 | |||
243 | return null; |
||
244 | } |
||
245 | |||
246 | /////////////////////////////////////////////////////////////////////////// |
||
247 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
||
248 | /////////////////////////////////////////////////////////////////////////// |
||
19 | office | 249 | /// <summary>Return all the run-time properties for an object.</summary> |
250 | /// <param name="o">the object whose properties to return</param> |
||
251 | /// <returns>the property information for all the properties of the object</returns> |
||
252 | public static IEnumerable<PropertyInfo> GetPropertiesInfo<T>(this T o) |
||
253 | { |
||
254 | foreach (var p in o.GetType().GetRuntimeProperties()) |
||
255 | yield return p; |
||
256 | } |
||
257 | |||
258 | /////////////////////////////////////////////////////////////////////////// |
||
259 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
||
260 | /////////////////////////////////////////////////////////////////////////// |
||
39 | office | 261 | /// <summary>Return all the run-time properties for an object.</summary> |
262 | /// <param name="o">the object whose properties to return</param> |
||
263 | /// <returns>the property information for all the properties of the object</returns> |
||
264 | public static IEnumerable<FieldInfo> GetFieldsInfo<T>(this T o) |
||
265 | { |
||
266 | foreach (var p in o.GetType().GetRuntimeFields()) |
||
267 | yield return p; |
||
268 | } |
||
269 | |||
270 | /////////////////////////////////////////////////////////////////////////// |
||
271 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
||
272 | /////////////////////////////////////////////////////////////////////////// |
||
7 | office | 273 | /// <summary> |
274 | /// Enumerate all the base types recursively starting from a type. |
||
275 | /// </summary> |
||
276 | /// <param name="type">the type</param> |
||
277 | /// <returns>an enumeration of all base types</returns> |
||
278 | public static IEnumerable<Type> GetBaseTypes(this Type type) |
||
279 | { |
||
280 | var baseType = type.GetTypeInfo().BaseType; |
||
10 | office | 281 | if (baseType == null) |
7 | office | 282 | yield break; |
283 | yield return baseType; |
||
284 | foreach (var t in GetBaseTypes(baseType)) |
||
285 | { |
||
286 | yield return t; |
||
287 | } |
||
288 | } |
||
289 | |||
290 | /// <summary> |
||
3 | eva | 291 | /// A generic name attribute. |
292 | /// </summary> |
||
293 | public class NameAttribute : Attribute |
||
294 | { |
||
295 | protected readonly string name; |
||
296 | |||
297 | public NameAttribute(string name) |
||
298 | { |
||
299 | this.name = name; |
||
300 | } |
||
301 | |||
302 | public string Name => name; |
||
303 | } |
||
304 | |||
305 | /// <summary> |
||
306 | /// A generic description attribute. |
||
307 | /// </summary> |
||
308 | public class DescriptionAttribute : Attribute |
||
309 | { |
||
310 | protected readonly string description; |
||
311 | |||
312 | public DescriptionAttribute(string description) |
||
313 | { |
||
314 | this.description = description; |
||
315 | } |
||
316 | |||
317 | public string Description => description; |
||
318 | } |
||
2 | zed | 319 | } |
27 | office | 320 | } |