繁体   English   中英

用于检测(通过反射)枚举是否为 C# 中的“标志”类型的策略

[英]Strategy for detecting (via Reflection) if Enum is of type "Flags" in C#

我正在使用反射来读取程序集中的类型(以生成代码)。 我可以看到一些枚举应该被标记为[Flags]属性,但是编写这些枚举的人忘记添加这个属性。

有什么可靠的方法可以检测枚举何时可以被视为“标志”枚举?

我目前的策略是按降序读取枚举,并检查 element(last -1) * 2 == element(last) 的值。

这在大多数情况下都很好用,除非我的枚举值为 0、1 和 2(可能是标志,也可能不是)。


编辑:

我想检测为标志的枚举示例:

public enum EnumIsFlag1
{
    ItemA = 2,
    ItemB = 4,
    ItemC = ItemA + ItemB,
    ItemD = 32,
    ItemE = 64,
}

编辑:我的问题不是重复的...版主显然没有阅读我的问题

显然,这个问题只能启发式解决,但我知道这就是你所追求的。

通常,标志枚举的大多数成员都设置了单个位。 所以我会计算只有一个位集(例如,是二的幂)的成员的数量。

然后,您可以设计一种启发式方法,例如:

//Is this a flags enum?

var totalCount = ...;
var powerOfTwoCount = ...;

if (totalCount < 3) return false; //Can't decide.
if (powerOfTwoCount >= totalCount * 0.95) return true; //Looks like flags
//Probably need some cases for small values of totalCount.

可以在合法标志枚举中设置多个位的唯一原因是标志的组合。 但此类枚举项的数量通常很少。

这个答案详细介绍了两者之间的差异,它们非常小:只是一些字符串格式化行为。

对您的问题的严格回答是,可以使用反射检查任何类型的标志枚举。 其他任何事情都需要由人来检查。 您可以像这样直接检查 Flags 属性;

[Flags]
enum Foo
{
    A = 0,
    B = 1,
    C = 4
}

enum Bar
{
    A = 0,
    B = 1,
    C = 4
}


bool IsFlagsEnum(Type t) 
{
    var attr = t.GetCustomAttributes(typeof(FlagsAttribute), true).FirstOrDefault();
    var result = attr != null;
    return result;
}

Console.WriteLine(IsFlagsEnum(typeof(Foo))); // True
Console.WriteLine(IsFlagsEnum(typeof(Bar))); // False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM