枚举中定义的项目总数

Ras*_*dit 298 .net c# enums

如何获取枚举中定义的项目数?

Kas*_*dum 402

您可以使用static方法Enum.GetNames返回一个数组,该数组表示枚举中所有项的名称.此数组的length属性等于枚举中定义的项数

var myEnumMemberCount = Enum.GetNames(typeof(MyEnum)).Length;
Run Code Online (Sandbox Code Playgroud)

  • 也可以使用Enum.GetValues. (8认同)
  • System.Enum.GetNames,如果您尚未包含System命名空间. (6认同)
  • 所以我今天刚刚遇到这个问题; 下面其他答案中描述的C风格技巧被列为有问题,但上面列出的Enum.GetValues和Enum.GetNames似乎都冒险分配一个全新的数组只是为了得到一个固定的长度,这似乎......好吧太可怕了 有谁知道这种方法确实会产生动态分配吗?如果是这样,对于某些用例,如果不是最灵活的话,它似乎是最有效的解决方案. (4认同)
  • @JTrana 是的,我刚刚追踪到了一些意外的分配:在循环条件下通过 Enum.GetNames 重复获取这个长度(乍一看并不明显,因为它位于属性的 getter 中)。因此,至少,请确保在第一次获取该值时将其缓存在某处。遗憾的是我们无法将其作为编译时常量。 (2认同)

Tim*_*lds 171

问题是:

如何获取枚举中定义的项目数?

"项目"的数量可能真的意味着两件完全不同的东西.请考虑以下示例.

enum MyEnum
{
    A = 1,
    B = 2,
    C = 1,
    D = 3,
    E = 2
}
Run Code Online (Sandbox Code Playgroud)

定义的"项目"数量是多少MyEnum

物品数量是5?(A,B,C,D,E)

还是3?(1,2,3)

(5)中定义的名称数量MyEnum可以如下计算.

var namesCount = Enum.GetNames(typeof(MyEnum)).Length;
Run Code Online (Sandbox Code Playgroud)

(3)中定义的的数量MyEnum可以如下计算.

var valuesCount = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Distinct().Count();
Run Code Online (Sandbox Code Playgroud)

  • 我想不出我生命中遇到的任何开发人员,他们肯定这样的枚举包含3个项目. (3认同)
  • 另一种写最后一行的方法,`var valuesCount =((MyEnum [])Enum.GetValues(typeof(MyEnum))).Distinct().Count();`. (2认同)
  • @motoDrizzt 你可以在打印机驱动程序的枚举中找到类似的东西,比如`Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...`;)。 (2认同)

Mat*_*ton 72

Enum.GetValues(typeof(MyEnum)).长度;

  • 使用GetNames方法更快. (6认同)

Jos*_*osh 14

我在C回答这个问题时看到的一个漂亮的技巧,只需在枚举中添加最后一个元素并使用它来说明枚举中有多少元素:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}
Run Code Online (Sandbox Code Playgroud)

在您定义0以外的起始值的情况下,可以使用NumberOfTypes - Type1来确定元素的数量.

我不确定这种方法是否比使用Enum更快,而且我也不确定它是否被认为是正确的方法,因为我们让Enum为我们确定这些信息.

  • 注意通过foreach遍历枚举的代码 - 你可以读出数组的末尾! (4认同)
  • 另外,要注意定义自己值的枚举 - 我经常使用枚举来进行位标记. (4认同)
  • 还要注意与某些 wpf 控件(例如组合框和列表框)的直接枚举绑定 (2认同)

小智 13

我今天运行了一个基准测试并得出了有趣的结果。在这三个中:

var count1 = typeof(TestEnum).GetFields().Length;
var count2 = Enum.GetNames(typeof(TestEnum)).Length;
var count3 = Enum.GetValues(typeof(TestEnum)).Length;
Run Code Online (Sandbox Code Playgroud)

GetNames(enum) 是迄今为止最快的!

|         Method |      Mean |    Error |   StdDev |
|--------------- |---------- |--------- |--------- |
| DeclaredFields |  94.12 ns | 0.878 ns | 0.778 ns |
|       GetNames |  47.15 ns | 0.554 ns | 0.491 ns |
|      GetValues | 671.30 ns | 5.667 ns | 4.732 ns |
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用Enum.GetNames在枚举中返回IEnumerable值,然后使用.Count生成IEnumerable.

GetNames产生的结果与GetValues大致相同,但速度更快.


jva*_*erh 6

从以前的答案中只添加代码示例.

 class Program
    {
        static void Main(string[] args)
        {
            int enumlen = Enum.GetNames(typeof(myenum)).Length;
            Console.Write(enumlen);
            Console.Read();
        }
        public enum myenum
        {
            value1,
            value2
        }
    }
Run Code Online (Sandbox Code Playgroud)


Mat*_*ins 5

如果您发现自己像我一样经常编写上述解决方案,则可以将其作为通用实现:

public static int GetEnumEntries<T>() where T : struct, IConvertible 
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T must be an enumerated type");

    return Enum.GetNames(typeof(T)).Length;
}
Run Code Online (Sandbox Code Playgroud)