Comparing enum flags in C#

后端 未结 7 1506
囚心锁ツ
囚心锁ツ 2021-02-07 18:37

I need to detect if a flag is set within an enum value, which type is marked with the Flag attribute.

Usually it is made like that:

(value & flag) ==         


        
7条回答
  •  盖世英雄少女心
    2021-02-07 19:20

    This should do the job for enum types with any underlying types:

    public static bool IsSet(this T value, T flags) where T : struct
    {
        return (Convert.ToInt64(value) & Convert.ToInt64(flags)) ==
            Convert.ToInt64(flags);
    }
    

    Convert.ToInt64 is used because a 64-bit integer is the "widest" integral type possible, to which all enum values can be cast (even ulong). Note that char is not a valid underlying type. It seems that it is not valid in C#, but it is in general valid in CIL/for the CLR.

    Also, you can't enforce a generic type constraint for enums (i.e. where T : struct); the best you can do is use where T : struct to enforce T to be a value type, and then optionally perform a dynamic check to ensure that T is an enum type.

    For completeness, here is my very brief test harness:

    static class Program
    {
        static void Main(string[] args)
        {
            Debug.Assert(Foo.abc.IsSet(Foo.abc));
            Debug.Assert(Bar.def.IsSet(Bar.def));
            Debug.Assert(Baz.ghi.IsSet(Baz.ghi));
        }
    
        enum Foo : int
        {
            abc = 1,
            def = 10,
            ghi = 100
        }
    
        enum Bar : sbyte
        {
            abc = 1,
            def = 10,
            ghi = 100
        }
    
        enum Baz : ulong
        {
            abc = 1,
            def = 10,
            ghi = 100
        }
    }
    

提交回复
热议问题