/// <summary>
        /// Initializes the <see cref="EnumInfo{TEnum}"/> for the enum type <typeparamref name="TEnum"/>.
        /// </summary>
        static EnumInfo()
        {
            Type           = typeof(TEnum);
            UnderlyingType = Enum.GetUnderlyingType(Type);
            IsUInt64       = UnderlyingType == typeof(ulong);
            if (!typeof(TEnum).IsEnum)
            {
                throw new ArgumentException($"{Type.Name} is not an enum!",
                                            nameof(TEnum));
            }
            DefaultValue = default;

            nameLookup           = new Dictionary <string, EnumFieldInfo <TEnum> >();
            nameLookupIgnoreCase = new Dictionary <string, EnumFieldInfo <TEnum> >(StringComparer.InvariantCultureIgnoreCase);
            valueLookup          = new Dictionary <TEnum, EnumFieldInfo <TEnum> >();

            foreach (FieldInfo field in Type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
            {
                var info = new EnumFieldInfo <TEnum>(field, IsUInt64);
                nameLookup.Add(info.Name, info);
                // Just incase this enum can't handle ignore-case.
                if (!nameLookupIgnoreCase.ContainsKey(info.Name))
                {
                    nameLookupIgnoreCase.Add(info.Name, info);
                }
                // Ignore duplicate enum values
                if (!valueLookup.ContainsKey(info.Value))
                {
                    valueLookup.Add(info.Value, info);
                }
            }
            Fields          = Array.AsReadOnly(nameLookup.Values.ToArray());
            HasDefaultField = valueLookup.ContainsKey(DefaultValue);
        }
 /// <summary>
 /// Tries to get the field for the specified enum value name.
 /// </summary>
 /// <param name="name">The name of the enum value.</param>
 /// <param name="field">The output field if one is found, otherwise null.</param>
 /// <returns>True if a field was found with the specified name.</returns>
 ///
 /// <exception cref="ArgumentNullException">
 /// <paramref name="name"/> is null.
 /// </exception>
 public static bool TryGetField(string name, out EnumFieldInfo <TEnum> field)
 {
     return(nameLookup.TryGetValue(name, out field));
 }
 /// <summary>
 /// Tries to get the field for the specified enum value name.
 /// </summary>
 /// <param name="name">The name of the enum value.</param>
 /// <param name="ignoreCase">True if the name casing can be ignored.</param>
 /// <param name="field">The output field if one is found, otherwise null.</param>
 /// <returns>True if a field was found with the specified name.</returns>
 ///
 /// <exception cref="ArgumentNullException">
 /// <paramref name="name"/> is null.
 /// </exception>
 public static bool TryGetField(string name, bool ignoreCase, out EnumFieldInfo <TEnum> field)
 {
     return(GetNameLookup(ignoreCase).TryGetValue(name, out field));
 }
 /// <summary>
 /// Tries to get the field for the specified enum value.
 /// </summary>
 /// <param name="value">The value of the enum.</param>
 /// <param name="field">The output field if one is found, otherwise null.</param>
 /// <returns>True if a field was found with the specified value.</returns>
 public static bool TryGetField(TEnum value, out EnumFieldInfo <TEnum> field)
 {
     return(valueLookup.TryGetValue(value, out field));
 }