Generic extension method to see if an enum contains a flag

前端 未结 8 1113
闹比i
闹比i 2021-02-01 01:56

Considering this:

[Flags]
public enum MyEnum {
    One = 1,
    Two = 2,
    Four = 4,
    Eight = 8
}

public static class FlagsHelper
{
    public static bool          


        
8条回答
  •  长发绾君心
    2021-02-01 02:23

    I have another approach here that I just cooked up quickly using the fact that Delegate.CreateDelegate allows conversion between methods for Enum's and their underlying types. The following approach is much like my previous answer but I feel might be easier to read for people who don't know expression tree syntax. Basically we know that Enums only have 8 possible underlying types, and so we just create a static method for each call it could use. Since I'm going for brevity I use anonymous methods which happened to be named the same thing as the possible typecode values.This approach will work in .Net 3.5::

    public static class EnumHelper
    {
        delegate bool HasFlag(T left,T right);
        static readonly HasFlag Byte = (x,y)=> (x&y) ==y;
        static readonly HasFlag Sbyte = (x,y)=> (x&y) ==y;
        static readonly HasFlag Int16 = (x,y)=> (x&y) ==y;
        static readonly HasFlag UInt16 = (x,y)=> (x&y) ==y;
        static readonly HasFlag Int32 = (x,y)=> (x&y) ==y;
        static readonly HasFlag UInt32 = (x,y)=> (x&y) ==y;
        static readonly HasFlag Int64 = (x,y)=> (x&y) ==y;
        static readonly HasFlag UInt64 = (x,y)=> (x&y) ==y;
    
        public static bool HasFlags(this TEnum @enum,TEnum flag) where TEnum:struct,IConvertible,IComparable,IFormattable
        {
            return Enum.HasFlag(@enum,flag);
        }
        class Enum where TEnum:struct,IConvertible,IComparable,IFormattable
        {
            public static HasFlag HasFlag = CreateDelegate();
            static HasFlag CreateDelegate()
            {
                if (!typeof(TEnum).IsEnum) throw new ArgumentException(string.Format("{0} is not an enum", typeof(TEnum)), typeof(Enum<>).GetGenericArguments()[0].Name);
                var delegateName = Type.GetTypeCode(typeof(TEnum)).ToString();
                var @delegate = typeof(EnumHelper).GetField(delegateName,BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Delegate;
                return Delegate.CreateDelegate(typeof(HasFlag), @delegate.Method) as HasFlag;
            }
        }
    }
    

提交回复
热议问题