枚举中定义的项目总数


Answers:


430

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

var myEnumMemberCount = Enum.GetNames(typeof(MyEnum)).Length;

1
同意...这是我找到的链接csharp411.com/c-count-items-in-an-enum
SO用户

8
也可以使用Enum.GetValues。
Xonatron 2014年

6
System.Enum.GetNames(如果尚未包含System命名空间)。
Brett Pennings

4
所以今天我又遇到了这个问题。下文其他答案中描述的C风格技巧被认为是有问题的,但上面列出的Enum.GetValues和Enum.GetNames似乎冒着分配整个新数组以获取固定长度的风险,这似乎很好。 ,太可怕了。有人知道这种方法是否确实需要动态分配吗?如果是这样,那么对于某些用例,即使不是最灵活的,也似乎是性能最高的解决方案。
J特拉纳

174

问题是:

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

“项目”的数量实际上可能意味着两个完全不同的事物。考虑以下示例。

enum MyEnum
{
    A = 1,
    B = 2,
    C = 1,
    D = 3,
    E = 2
}

中定义的“项目”数量是多少MyEnum

项目数是5吗?(ABCDE

还是3?(123

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

var namesCount = Enum.GetNames(typeof(MyEnum)).Length;

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

var valuesCount = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Distinct().Count();

2
写最后一行的另一种方法var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();
杰普·斯蒂格·尼尔森

3
我想不起我一生中遇到过的任何开发人员,他们肯定这样的枚举包含3个项目。
motoDrizzt

2
@motoDrizzt可以在打印机驱动程序的枚举中找到类似的东西Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;)。
shA.t


14

我在C答案中看到的一个巧妙技巧,只需在枚举中添加最后一个元素,然后使用它来告诉枚举中有多少个元素:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

如果您定义的起始值不是0,则可以使用NumberOfTypes-Type1来确定元素数。

我不确定此方法是否会比使用Enum更快,并且我也不确定是否将其视为执行此操作的正确方法,因为我们有Enum可以为我们确定此信息。


1
这很好,因为我可以在XNA上执行此操作,因为那里没有GetNames
Thiago Valle

很酷的技巧,它也比GetNames()更快,因为它不必计算它们。
Jordan LaPrise

4
当心通过foreach在枚举中循环的代码-您可以读取数组的结尾!
Michael Dorgan 2014年

4
另外,请注意定义自己值的枚举-我经常将枚举用于位标志。
马特·帕金斯

1
还请注意直接将枚举绑定到一些wpf控件,例如combobox和listbox
mcy 2015年

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
        }
    }

5

您可以使用Enum.GetNames返回枚举中的IEnumerable值,然后.Count得到的IEnumerable。

GetNames产生的结果与GetValues几乎相同,但速度更快。


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;
}

1

我刚才正在研究这个问题,对当前解决方案的可读性不满意。如果您是非正式地编写代码或在一个小型项目上编写代码,则可以在枚举的末尾添加另一个名为“长度”的项目。这样,您只需要键入:

var namesCount = (int)MyEnum.Length;

当然,如果其他人要使用您的代码-或者我确定在这种情况下不适用于我的许多其他情况-这种解决方案可能是不明智的,甚至是糟糕的。


2
这也依赖于从0开始的枚举(默认值,但绝不能保证)。另外,它使普通枚举用法的智能感知非常混乱。这几乎总是一个可怕的主意。
BradleyDotNET 2014年

2
没多久:)
EnergyWasRaw 2014年

1
有趣的是,我想您永远不会知道何时会出现更好的情况。我尽最大努力避免使用自己的解决方案,但发现它很有趣,可以分享!
EnergyWasRaw 2014年

1

对于Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Length不能和我一起工作,但是可以 [Enum].GetNames(GetType(Animal_Type)).length


为什么要下票?这解决了我的问题,这是VB的正确语法,即使该问题被标记为c#,仍然有用。
M Granja

2
拒绝投票可能是因为问题被标记为C#,而此答案并未提及它未使用C#。
idbrii
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.