-
Notifications
You must be signed in to change notification settings - Fork 5
/
Enum2.cs
481 lines (436 loc) · 16.4 KB
/
Enum2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
using System;
using System.Globalization;
using System.Collections;
using System.Linq;
using System.Text;
using Crestron.SimplSharp.Reflection;
namespace OpenNETCF
{
/// <summary>
/// Provides helper functions for Enumerations.
/// </summary>
/// <remarks>Extends the <see cref="System.Enum">System.Enum Class</see>.</remarks>
/// <seealso cref="System.Enum">System.Enum Class</seealso>
public static class Enum2
{
#region Get Name
/// <summary>
/// Retrieves the name of the constant in the specified enumeration that has the specified value.
/// </summary>
/// <param name="enumType">An enumeration type.</param>
/// <param name="value">The value of a particular enumerated constant in terms of its underlying type.</param>
/// <returns> A string containing the name of the enumerated constant in enumType whose value is value, or null if no such constant is found.</returns>
/// <exception cref="System.ArgumentException"> enumType is not an System.Enum. -or- value is neither of type enumType nor does it have the same underlying type as enumType.</exception>
/// <example>The following code sample illustrates the use of GetName (Based on the example provided with desktop .NET Framework):
/// <code>[Visual Basic]
/// Imports System
///
/// Public Class GetNameTest
///
/// Enum Colors
/// Red
/// Green
/// Blue
/// Yellow
/// End Enum 'Colors
///
/// Enum Styles
/// Plaid
/// Striped
/// Tartan
/// Corduroy
/// End Enum 'Styles
///
/// Public Shared Sub Main()
/// MessageBox.Show("The 4th value of the Colors Enum is " + [OpenNETCF.Enum].GetName(GetType(Colors), 3))
/// MessageBox.Show("The 4th value of the Styles Enum is " + [OpenNETCF.Enum].GetName(GetType(Styles), 3))
/// End Sub 'Main
///
/// End Class 'GetNameTest</code>
/// <code>[C#]
/// using System;
///
/// public class GetNameTest
/// {
/// enum Colors { Red, Green, Blue, Yellow };
/// enum Styles { Plaid, Striped, Tartan, Corduroy };
///
/// public static void Main()
/// {
/// MessageBox.Show("The 4th value of the Colors Enum is " + OpenNETCF.Enum.GetName(typeof(Colors), 3));
/// MessageBox.Show("The 4th value of the Styles Enum is " + OpenNETCF.Enum.GetName(typeof(Styles), 3));
/// }
/// }</code>
/// </example>
/// <seealso cref="M:System.Enum.GetName(System.Type,System.Object)">System.Enum.GetName Method</seealso>
public static string GetName (Type enumType, object value)
{
//check that the type supplied inherits from System.Enum
if (enumType.BaseType == Type.GetType ("System.Enum"))
{
//get details of all the public static fields (enum items)
FieldInfo[] fi = enumType.GetCType ().GetFields (BindingFlags.Static | BindingFlags.Public);
//cycle through the enum values
foreach (FieldInfo thisField in fi)
{
object numericValue = 0;
try
{
//convert the enum value to the numeric type supplied
numericValue = Convert.ChangeType (thisField.GetValue (null), value.GetType (), null);
}
catch
{
throw new ArgumentException ();
}
//if value matches return the name
if (numericValue.Equals (value))
{
return thisField.Name;
}
}
//if there is no match return null
return null;
}
else
{
//the type supplied does not derive from enum
throw new ArgumentException ("enumType parameter is not an System.Enum");
}
}
#endregion
#region Get Names
/// <summary>
/// Retrieves an array of the names of the constants in a specified enumeration.
/// </summary>
/// <param name="enumType">An enumeration type.</param>
/// <returns>A string array of the names of the constants in enumType. The elements of the array are sorted by the values of the enumerated constants.</returns>
/// <exception cref="System.ArgumentException">enumType parameter is not an System.Enum</exception>
/// <example>The follow example shows how to enumerate the members of the System.DayOfWeek enumeration by adding them to a ComboBox:-
/// <code>[Visual Basic]
/// Dim thisDOW As New DayOfWeek
/// For Each thisDOW In OpenNETCF.Enum.GetValues(Type.GetType("System.DayOfWeek"))
/// ComboBox1.Items.Add(thisDOW)
/// Next</code>
/// <code>[C#]
/// foreach(DayOfWeek thisdow in OpenNETCF.Enum.GetValues(typeof(DayOfWeek)))
/// {
/// comboBox1.Items.Add(thisdow);
/// }</code></example>
/// <seealso cref="M:System.Enum.GetNames(System.Type)">System.Enum.GetNames Method</seealso>
public static string[] GetNames (Type enumType)
{
if (enumType.BaseType == Type.GetType ("System.Enum"))
{
//get the public static fields (members of the enum)
FieldInfo[] fi = enumType.GetCType ().GetFields (BindingFlags.Static | BindingFlags.Public);
//create a new enum array
string[] names = new string[fi.Length];
//populate with the values
for (int iEnum = 0; iEnum < fi.Length; iEnum++)
{
names[iEnum] = fi[iEnum].Name;
}
//return the array
return names;
}
else
{
//the type supplied does not derive from enum
throw new ArgumentException ("enumType parameter is not an System.Enum");
}
}
#endregion
#region Get Underlying Type
/// <summary>
/// Returns the underlying type of the specified enumeration.>
/// </summary>
/// <param name="enumType">An enumeration type.</param>
/// <returns>The underlying <see cref="System.Type"/> of <paramref>enumType</paramref>.</returns>
/// <seealso cref="M:System.Enum.GetUnderlyingType(System.Type)">System.Enum.GetUnderlyingType Method</seealso>
public static Type GetUnderlyingType (Type enumType)
{
return Enum.GetUnderlyingType (enumType);
}
#endregion
#region Get Values
/// <summary>
/// Retrieves an array of the values of the constants in a specified enumeration.
/// </summary>
/// <param name="enumType">An enumeration type.</param>
/// <returns>An System.Array of the values of the constants in enumType. The elements of the array are sorted by the values of the enumeration constants.</returns>
/// <exception cref="System.ArgumentException">enumType parameter is not an System.Enum</exception>
/// <seealso cref="M:System.Enum.GetValues(System.Type)">System.Enum.GetValues Method</seealso>
public static Array GetValues (Type enumType)
{
if (enumType.BaseType == Type.GetType ("System.Enum"))
{
//get the public static fields (members of the enum)
FieldInfo[] fi = enumType.GetCType ().GetFields (BindingFlags.Static | BindingFlags.Public);
//create a new enum array
var values = Array.CreateInstance (enumType, fi.Length);
//populate with the values
for (int iEnum = 0; iEnum < fi.Length; iEnum++)
{
values.SetValue(Enum.ToObject (enumType, fi[iEnum].GetValue (null)), iEnum);
}
//return the array
return values;
}
else
{
//the type supplied does not derive from enum
throw new ArgumentException ("enumType parameter is not an System.Enum");
}
}
public static Enum[] GetEnumValues (Type enumType)
{
if (enumType.BaseType == Type.GetType ("System.Enum"))
{
//get the public static fields (members of the enum)
FieldInfo[] fi = enumType.GetCType ().GetFields (BindingFlags.Static | BindingFlags.Public);
//create a new enum array
Enum[] values = new Enum[fi.Length];
//populate with the values
for (int iEnum = 0; iEnum < fi.Length; iEnum++)
{
values[iEnum] = (Enum)fi[iEnum].GetValue (null);
}
//return the array
return values;
}
else
{
//the type supplied does not derive from enum
throw new ArgumentException ("enumType parameter is not an System.Enum");
}
}
#endregion
#region Is Defined
/// <summary>
/// Returns an indication whether a constant with a specified value exists in a specified enumeration.
/// </summary>
/// <param name="enumType">An enumeration type.</param>
/// <param name="value">The value or name of a constant in enumType.</param>
/// <returns><b>true</b> if a constant in <paramref>enumType</paramref> has a value equal to value; otherwise, <b>false</b>.</returns>
/// <seealso cref="M:System.Enum.IsDefined(System.Type,System.Object)">System.Enum.IsDefined Method</seealso>
public static bool IsDefined (Type enumType, object value)
{
return Enum.IsDefined (enumType, value);
}
#endregion
#region Parse
/// <summary>
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <param name="enumType">The <see cref="T:System.Type"/> of the enumeration.</param>
/// <param name="value">A string containing the name or value to convert.</param>
/// <returns>An object of type enumType whose value is represented by value.</returns>
public static object Parse (Type enumType, string value)
{
//do case sensitive parse
return Enum.Parse (enumType, value, false);
}
/// <summary>
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
/// A parameter specifies whether the operation is case-sensitive.
/// </summary>
/// <param name="enumType">The <see cref="T:System.Type"/> of the enumeration.</param>
/// <param name="value">A string containing the name or value to convert.</param>
/// <param name="ignoreCase">If true, ignore case; otherwise, regard case.</param>
/// <returns>An object of type enumType whose value is represented by value.</returns>
/// <exception cref="System.ArgumentException">enumType is not an <see cref="T:System.Enum"/>.
/// -or- value is either an empty string ("") or only contains white space.
/// -or- value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <seealso cref="M:System.Enum.Parse(System.Type,System.String,System.Boolean)">System.Enum.Parse Method</seealso>
public static object Parse (Type enumType, string value, bool ignoreCase)
{
return Enum.Parse (enumType, value, ignoreCase);
}
#endregion
#region To Object
/// <summary>
/// Returns an instance of the specified enumeration set to the specified value.
/// </summary>
/// <param name="enumType">An enumeration.</param>
/// <param name="value">The value.</param>
/// <returns>An enumeration object whose value is <paramref>value</paramref>.</returns>
/// <seealso cref="System.Enum.ToObject(System.Type, System.Object)">System.Enum.ToObject Method</seealso>
public static object ToObject (Type enumType, object value)
{
return Enum.ToObject (enumType, value);
}
#endregion
#region Format
private static string InternalFormat (Type enumType, object value)
{
if (enumType.IsDefined (typeof (FlagsAttribute), false))
return InternalFlagsFormat (enumType, value);
string t = GetName (enumType, value);
if (t == null)
return value.ToString ();
return t;
}
internal static ulong ToUInt64 (object value)
{
switch (Convert.GetTypeCode (value))
{
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return Convert.ToUInt64 (value, CultureInfo.InvariantCulture);
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
return (ulong)Convert.ToInt64 (value, CultureInfo.InvariantCulture);
}
throw new InvalidOperationException ("UnknownEnumType");
}
private static string InternalFlagsFormat (Type enumType, object value)
{
//string t = GetName (enumType, value);
//if (t == null)
// return value.ToString ();
//return t;
string[] names = Enum2.GetNames (enumType);
ulong[] values = Enum2.GetEnumValues (enumType).Select (v => ToUInt64 (v)).ToArray ();
ulong num = ToUInt64 (value);
int index = values.Length - 1;
var builder = new StringBuilder ();
bool flag = true;
ulong num3 = num;
while (index >= 0)
{
if ((index == 0) && (values[index] == 0))
{
break;
}
if ((num & values[index]) == values[index])
{
num -= values[index];
if (!flag)
{
builder.Insert (0, ", ");
}
builder.Insert (0, names[index]);
flag = false;
}
index--;
}
if (num != 0)
{
return value.ToString ();
}
if (num3 != 0)
{
return builder.ToString ();
}
if ((values.Length != 0) && (values[0] == 0))
{
return names[0];
}
return "0";
}
private static string InternalValuesFormat (Type enumType, object value, bool showValues)
{
string[] names = null;
if (!showValues) names = GetNames (enumType);
ulong v = Convert.ToUInt64 (value);
Enum[] e = GetEnumValues (enumType);
ArrayList al = new ArrayList ();
for (int i = 0; i < e.Length; i++)
{
ulong ev = (ulong)Convert.ChangeType (e[i], typeof (ulong), null);
if (i == 0 && ev == 0) continue;
if ((v & ev) == ev)
{
v -= ev;
if (showValues)
al.Add (ev.ToString ());
else
al.Add (names[i]);
}
}
if (v != 0)
return value.ToString ();
string[] t = (string[])al.ToArray (typeof (string));
return string.Join (", ", t);
}
/// <summary>
/// Converts the specified value of a specified enumerated type to its equivalent string representation according to the specified format.
/// </summary>
/// <remarks>
/// The valid format values are:
/// "G" or "g" - If value is equal to a named enumerated constant, the name of that constant is returned; otherwise, the decimal equivalent of value is returned.
/// For example, suppose the only enumerated constant is named, Red, and its value is 1. If value is specified as 1, then this format returns "Red". However, if value is specified as 2, this format returns "2".
/// "X" or "x" - Represents value in hexadecimal without a leading "0x".
/// "D" or "d" - Represents value in decimal form.
/// "F" or "f" - Behaves identically to "G" or "g", except the FlagsAttribute is not required to be present on the Enum declaration.
/// "V" or "v" - If value is equal to a named enumerated constant, the value of that constant is returned; otherwise, the decimal equivalent of value is returned.
/// </remarks>
/// <param name="enumType">The enumeration type of the value to convert.</param>
/// <param name="value">The value to convert.</param>
/// <param name="format">The output format to use.</param>
/// <returns>A string representation of value.</returns>
public static string Format (Type enumType, object value, string format)
{
if (enumType == null) throw new ArgumentNullException ("enumType");
if (value == null) throw new ArgumentNullException ("value");
if (format == null) throw new ArgumentNullException ("format");
if (!enumType.IsEnum) throw new ArgumentException ("The argument enumType must be an System.Enum.");
if (string.Compare (format, "G", true, CultureInfo.InvariantCulture) == 0)
return InternalFormat (enumType, value);
if (string.Compare (format, "F", true, CultureInfo.InvariantCulture) == 0)
return InternalValuesFormat (enumType, value, false);
if (string.Compare (format, "V", true, CultureInfo.InvariantCulture) == 0)
return InternalValuesFormat (enumType, value, true);
if (string.Compare (format, "X", true, CultureInfo.InvariantCulture) == 0)
return InternalFormattedHexString (value);
if (string.Compare (format, "D", true, CultureInfo.InvariantCulture) == 0)
return Convert.ToUInt64 (value).ToString ();
throw new FormatException ("Invalid format.");
}
private static string InternalFormattedHexString (object value)
{
switch (Convert.GetTypeCode (value))
{
case TypeCode.SByte:
{
sbyte n = (sbyte)value;
return n.ToString ("X2", null);
}
case TypeCode.Byte:
{
byte n = (byte)value;
return n.ToString ("X2", null);
}
case TypeCode.Int16:
{
short n = (short)value;
return n.ToString ("X4", null);
}
case TypeCode.UInt16:
{
ushort n = (ushort)value;
return n.ToString ("X4", null);
}
case TypeCode.Int32:
{
int n = (int)value;
return n.ToString ("X8", null);
}
case TypeCode.UInt32:
{
uint n = (uint)value;
return n.ToString ("X8", null);
}
}
throw new InvalidOperationException ("Unknown enum type.");
}
#endregion
}
}