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

#1 楼

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

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


评论


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

– SO用户
09年5月13日下午5:45

也可以使用Enum.GetValues。

– Xonatron
2014年11月25日7:52

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

–布雷特·彭宁斯(Brett Pennings)
2015年2月3日,下午2:55

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

– J Trana
16年6月19日在20:58

#2 楼

问题是:


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


“项目”的数量可能真的意味着两件事完全不同。请考虑以下示例。

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


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

项目数是5吗? (ABCDE

还是3? (123

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

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


数字可以如下计算MyEnum(3)中定义的值的总和。

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


评论


写最后一行的另一种方法是var valuesCount =(((MyEnum [])Enum.GetValues(typeof(MyEnum)))。Distinct()。Count();。

–杰普·斯蒂格·尼尔森(Jeppe Stig Nielsen)
16年1月15日在19:12

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

–motoDrizzt
18年6月13日在7:09

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

–shA.t
18/12/27在8:08

#3 楼

Enum.GetValues(typeof(MyEnum))。Length;

评论


使用GetNames方法更快。

–卡斯珀·霍尔顿(Kasper Holdum)
09年5月13日下午5:11

结果应该缓存在实用程序类中吗?

– djmj
2014年9月4日上午10:56

#4 楼

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

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}


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

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

评论


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

– Thiago Valle
13年7月3日,在1:21

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

–乔丹·拉普瑞斯(Jordan LaPrise)
2014年2月24日在7:51

注意通过foreach在枚举中循环的代码-您可以读取数组的结尾!

– Michael Dorgan
2014年3月19日,0:01

另外,请注意定义自己值的枚举-我经常将枚举用于位标志。

–马特·帕金斯(Matt Parkins)
15年3月26日在11:01

还请注意直接将枚举绑定到某些wpf控件,例如组合框和列表框

–mcy
15年4月22日在11:29

#5 楼

从前面的答案中只需添加代码示例。

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


#6 楼

您可以使用Enum.GetNames返回枚举中的IEnumerable值,然后对所得IEnumerable进行计数。

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

#7 楼

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

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


#8 楼

我今天进行了基准测试,得出了有趣的结果。在这三个中:
var count1 = typeof(TestEnum).GetFields().Length;
var count2 = Enum.GetNames(typeof(TestEnum)).Length;
var count3 = Enum.GetValues(typeof(TestEnum)).Length;

到目前为止,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 |


#9 楼

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

var namesCount = (int)MyEnum.Length;


当然,如果其他人要使用您的代码-或我确定在许多其他情况下并没有使用您的代码在这种情况下适用于我-此解决方案可能从不建议到可怕的任何地方。

评论


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

– BradleyDotNET
2014年11月12日23:08

没多久:)

–EnergyWasRaw
2014年11月12日23:10

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

–EnergyWasRaw
2014年11月12日23:12



#10 楼

对于Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Length不适合我,但
[Enum].GetNames(GetType(Animal_Type)).length可以。

评论


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

– M Granja
15年4月20日在19:50

拒绝投票可能是因为问题被标记为C#,而此答案并未提及它未使用C#。

– idbrii
18年2月22日在19:01