簡體   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