using System.Collections.Generic; using System.ComponentModel; using System.Reflection; namespace System { internal static class EnumUtil { public static void CheckIsEnum(bool checkHasFlags = false) { if (!typeof(T).IsEnum) throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName)); if (checkHasFlags && !IsFlags()) throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName)); } public static bool IsFlags() { return Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)); } public static void CheckHasValue(T value, string argName = null) { CheckIsEnum(); if (IsFlags()) { long allFlags = 0L; foreach (T flag in Enum.GetValues(typeof(T))) allFlags |= Convert.ToInt64(flag); if ((allFlags & Convert.ToInt64(value)) != 0L) return; } else if (Enum.IsDefined(typeof(T), value)) return; throw new InvalidEnumArgumentException(argName == null ? "value" : argName, Convert.ToInt32(value), typeof(T)); } public static bool IsFlagSet(this T flags, T flag) where T : struct, IConvertible { CheckIsEnum(true); long flagValue = Convert.ToInt64(flag); return (Convert.ToInt64(flags) & flagValue) == flagValue; } public static void SetFlags(ref T flags, T flag, bool set = true) where T : struct, IConvertible { CheckIsEnum(true); long flagsValue = Convert.ToInt64(flags); long flagValue = Convert.ToInt64(flag); if (set) flagsValue |= flagValue; else flagsValue &= (~flagValue); flags = (T)Enum.ToObject(typeof(T), flagsValue); } public static T SetFlags(this T flags, T flag, bool set = true) where T : struct, IConvertible { T ret = flags; SetFlags(ref ret, flag, set); return ret; } public static T ClearFlags(this T flags, T flag) where T : struct, IConvertible { return flags.SetFlags(flag, false); } public static IEnumerable GetFlags(this T value) where T : struct, IConvertible { CheckIsEnum(true); foreach (T flag in Enum.GetValues(typeof(T))) { if (value.IsFlagSet(flag)) yield return flag; } } public static T CombineFlags(this IEnumerable flags) where T : struct, IConvertible { CheckIsEnum(true); long lValue = 0; foreach (T flag in flags) { long lFlag = Convert.ToInt64(flag); lValue |= lFlag; } return (T)Enum.ToObject(typeof(T), lValue); } public static string GetDescription(this T value) where T : struct, IConvertible { CheckIsEnum(); string name = Enum.GetName(typeof(T), value); if (name != null) { FieldInfo field = typeof(T).GetField(name); if (field != null) { DescriptionAttribute attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; if (attr != null) { return attr.Description; } } } return null; } } }