Strategy for detecting (via Reflection) if Enum is of type “Flags” in C#

痴心易碎 提交于 2021-02-16 18:26:09

问题


I'm using Reflection to read types inside an assembly (to generate code). I can see that some enumerations should have been marked with the [Flags] attribute but whoever wrote those enums forgot to add this attribute.

Is there any reliable way of detecting when an enum can be considered a "Flags" enum?

My strategy at the moment is to read the enum in descending order, and checking if the value of element(last -1) * 2 == element(last).

That works great in most cases, except when I have enums with 0, 1, and 2 values (which could be flags or not).


edit:

Example of an enum that I'd like to detect as being flags:

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

edit: My question is not a duplicate... The moderator clearly didn't read my question


回答1:


Clearly, this problem can only be solved heuristically but I understand that's what you are after.

Typically, flags enums have most members with a single bit set. So I would count the number of members that have only a single bit set (e.g. that are a power of two).

Then, you can devise a heuristic such as:

//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.

The only reason multiple bits could be set in a legitimate flags enum is combinations of flags. But the number of such enum items is usually small.




回答2:


This answer goes into detail about the differences between the two, and they are very minor: just some string formatting behaviour.

The strict answer to your question is that any type can be checked for the flags enum using reflection. Anything else just needs to be checked by a human. You can check for the Flags attribute directly like this;

[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


来源:https://stackoverflow.com/questions/34138312/strategy-for-detecting-via-reflection-if-enum-is-of-type-flags-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!