C#,Flags Enum,寻找标志的通用函数

jef*_*eff 13 c# enums enum-flags

我想要一个可以与任何Flags样式枚举一起使用的通用函数来查看是否存在标志.

这不会编译,但如果有人有建议,我会很感激.

public static Boolean IsEnumFlagPresent<T>(T value,T lookingForFlag) 
       where T:enum
{
    Boolean result = ((value & lookingForFlag) == lookingForFlag);
    return result ;            
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*ier 22

您是否希望用包含一行代码的函数替换一行代码?我要说只使用一行代码......

  • 这是一个很好的答案 - 我甚至没有想到回复那个问题.我直接进入了实施方面.自我注意:必须退后一步...... (6认同)
  • 神圣的牛,我比Skeet有更多的赞成.这不可能持续...... :-) (3认同)

Jon*_*eet 21

不,你不能用C#泛型做到这一点.但是,你可以这样做:

public static bool IsEnumFlagPresent<T>(T value, T lookingForFlag) 
    where T : struct
{
    int intValue = (int) (object) value;
    int intLookingForFlag = (int) (object) lookingForFlag;
    return ((intValue & intLookingForFlag) == intLookingForFlag);
}
Run Code Online (Sandbox Code Playgroud)

这只适用于具有底层类型的枚举int,并且它的效率有点低,因为它将值包装......但它应该有效.

您可能想要添加执行类型检查T实际上是枚举类型(例如typeof(T).BaseType == typeof(Enum))

这是一个完整的程序,展示了它的工作原理:

using System;

[Flags]
enum Foo
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}

class Test
{
    public static Boolean IsEnumFlagPresent<T>(T value, T lookingForFlag) 
        where T : struct
    {
        int intValue = (int) (object) value;
        int intLookingForFlag = (int) (object) lookingForFlag;
        return ((intValue & intLookingForFlag) == intLookingForFlag);
    }

    static void Main()
    {
        Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.A));
        Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.B));
        Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.C));
        Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.D));
    }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*idi 12

值得一提的是,我最近读到这个功能将成为.NET 4.0的一部分.具体来说,它是在Enum.HasFlag()函数中实现的.


Kle*_*nux 6

我以前用过这个:

public static bool In<T>(this T me, T values)
    where T : struct, IConvertible
{
    return (me.ToInt64(null) & values.ToInt64(null)) > 0;
}
Run Code Online (Sandbox Code Playgroud)

我喜欢它是你可以使用这个干净的语法来调用它,因为在3.5中编译器可以推断泛型参数.

AttributeTargets a = AttributeTargets.Class;
if (a.In(AttributeTargets.Class | AttributeTargets.Module))
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)