<PackageReference Include="Newtonsoft.Json" Version="8.0.2" />

EnumUtils

static class EnumUtils
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.Serialization; namespace Newtonsoft.Json.Utilities { internal static class EnumUtils { private static readonly ThreadSafeStore<Type, BidirectionalDictionary<string, string>> EnumMemberNamesPerType = new ThreadSafeStore<Type, BidirectionalDictionary<string, string>>(InitializeEnumType); private static BidirectionalDictionary<string, string> InitializeEnumType(Type type) { BidirectionalDictionary<string, string> bidirectionalDictionary = new BidirectionalDictionary<string, string>(StringComparer.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase); FieldInfo[] fields = type.GetFields(); foreach (FieldInfo fieldInfo in fields) { string name = fieldInfo.Name; string text = (from EnumMemberAttribute a in fieldInfo.GetCustomAttributes(typeof(EnumMemberAttribute), true) select a.Value).SingleOrDefault() ?? fieldInfo.Name; if (bidirectionalDictionary.TryGetBySecond(text, out string _)) throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'.".FormatWith(CultureInfo.InvariantCulture, text, type.Name)); bidirectionalDictionary.Set(name, text); } return bidirectionalDictionary; } public static IList<T> GetFlagsValues<T>(T value) where T : struct { Type typeFromHandle = typeof(T); if (!typeFromHandle.IsDefined(typeof(FlagsAttribute), false)) throw new ArgumentException("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, typeFromHandle)); Type underlyingType = Enum.GetUnderlyingType(value.GetType()); ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture); IList<EnumValue<ulong>> namesAndValues = GetNamesAndValues<T>(); IList<T> list = new List<T>(); foreach (EnumValue<ulong> item in (IEnumerable<EnumValue<ulong>>)namesAndValues) { if ((num & item.Value) == item.Value && item.Value != 0) ((ICollection<T>)list).Add((T)Convert.ChangeType(item.Value, underlyingType, CultureInfo.CurrentCulture)); } if (((ICollection<T>)list).Count == 0 && namesAndValues.SingleOrDefault((EnumValue<ulong> v) => v.Value == 0) != null) ((ICollection<T>)list).Add(default(T)); return list; } public static IList<EnumValue<ulong>> GetNamesAndValues<T>() where T : struct { return GetNamesAndValues<ulong>(typeof(T)); } public static IList<EnumValue<TUnderlyingType>> GetNamesAndValues<TUnderlyingType>(Type enumType) where TUnderlyingType : struct { if (enumType == (Type)null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum()) throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), "enumType"); IList<object> values = GetValues(enumType); IList<string> names = GetNames(enumType); IList<EnumValue<TUnderlyingType>> list = new List<EnumValue<TUnderlyingType>>(); for (int i = 0; i < ((ICollection<object>)values).Count; i++) { try { ((ICollection<EnumValue<TUnderlyingType>>)list).Add(new EnumValue<TUnderlyingType>(names[i], (TUnderlyingType)Convert.ChangeType(values[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture))); } catch (OverflowException innerException) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}", new object[3] { Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(values[i], CultureInfo.InvariantCulture) }), innerException); } } return list; } public static IList<object> GetValues(Type enumType) { if (!enumType.IsEnum()) throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); List<object> list = new List<object>(); foreach (FieldInfo item in from f in enumType.GetFields() where f.IsLiteral select f) { object value = item.GetValue(enumType); list.Add(value); } return list; } public static IList<string> GetNames(Type enumType) { if (!enumType.IsEnum()) throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); List<string> list = new List<string>(); foreach (FieldInfo item in from f in enumType.GetFields() where f.IsLiteral select f) { list.Add(item.Name); } return list; } public static object ParseEnumName(string enumText, bool isNullable, Type t) { if ((enumText == string.Empty) & isNullable) return null; BidirectionalDictionary<string, string> map = EnumMemberNamesPerType.Get(t); string value; if (enumText.IndexOf(',') != -1) { string[] array = enumText.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string enumText2 = array[i].Trim(); array[i] = ResolvedEnumName(map, enumText2); } value = string.Join(", ", array); } else value = ResolvedEnumName(map, enumText); return Enum.Parse(t, value, true); } public static string ToEnumName(Type enumType, string enumText, bool camelCaseText) { BidirectionalDictionary<string, string> bidirectionalDictionary = EnumMemberNamesPerType.Get(enumType); string[] array = enumText.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); bidirectionalDictionary.TryGetByFirst(text, out string second); second = (second ?? text); if (camelCaseText) second = StringUtils.ToCamelCase(second); array[i] = second; } return string.Join(", ", array); } private static string ResolvedEnumName(BidirectionalDictionary<string, string> map, string enumText) { map.TryGetBySecond(enumText, out string first); first = (first ?? enumText); return first; } } }