【问题标题】:Total number of items defined in an enum枚举中定义的项目总数
【发布时间】:2010-10-25 18:19:53
【问题描述】:

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

【问题讨论】:

    标签: c# .net enums


    【解决方案1】:

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

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

    【讨论】:

    • 同意...这是我找到的链接csharp411.com/c-count-items-in-an-enum
    • 也可以使用 Enum.GetValues。
    • System.Enum.GetNames,如果您尚未包含 System 命名空间。
    • 所以我今天又遇到了这个问题;下面其他答案中描述的 C 风格技巧被列为有问题,但上面列出的 Enum.GetValues 和 Enum.GetNames 似乎都冒着分配一个全新数组的风险,只是为了获得固定长度,这似乎......好吧,可怕。有谁知道这种方法是否确实会产生动态分配?如果是这样,那么对于某些用例来说,即使不是最灵活的,它似乎也是性能最高的解决方案。
    • @JTrana 是的,我刚刚追踪了一些意外的分配:属性的吸气剂)。因此,至少,请确保在您第一次获得该值时将其缓存在某处。很遗憾,我们无法将其作为编译时常量。
    【解决方案2】:

    问题是:

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

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

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

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

    项目数是 5 吗? (A, B, C, D, E)

    还是 3? (1, 2, 3)

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

    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();
    • 我想不出我一生中遇到的任何开发人员会肯定这样的枚举包含 3 个项目。
    • @motoDrizzt 你可以在像Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...这样的打印机驱动程序的枚举中找到类似的东西;)。
    【解决方案3】:

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

    【讨论】:

    • 使用GetNames方法更快。
    【解决方案4】:

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

    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 |
    

    【讨论】:

      【解决方案5】:

      我在这个问题的 C 回答中看到的一个绝妙技巧,只需将最后一个元素添加到枚举中并用它来判断枚举中有多少元素:

      enum MyType {
        Type1,
        Type2,
        Type3,
        NumberOfTypes
      }
      

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

      我不确定这种方法是否会比使用 Enum 更快,我也不确定它是否被认为是执行此操作的正确方法,因为我们有 Enum 为我们确定此信息。

      【讨论】:

      • 这很好,因为我可以在 XNA 上这样做,因为 GetNames 在那里不可用
      • 很酷的技巧,这也比 GetNames() 更快,因为它不必计算它们。
      • 当心通过 foreach 循环遍历枚举的代码 - 您可以读取数组的末尾!
      • 另外,请注意定义自己的值的枚举 - 我经常将枚举用于位标志。
      • 还要注意直接枚举绑定到一些 wpf 控件,例如组合框和列表框
      【解决方案6】:

      您可以使用 Enum.GetNames 在您的枚举中返回一个 IEnumerable 值,然后对生成的 IEnumerable 进行计数。

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

          如果您发现自己像我一样经常编写上述解决方案,那么您可以将其实现为泛型:

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

          【讨论】:

            【解决方案9】:

            对于 Visual Basic:

            [Enum].GetNames(typeof(MyEnum)).Length 不适合我,但是 [Enum].GetNames(GetType(Animal_Type)).length 做到了。

            【讨论】:

            • 为什么投反对票?这解决了我的问题,它是 VB 的正确语法,即使问题标记为 c#,仍然有用。
            • 投反对票可能是因为问题被标记为 C# 而这个答案没有提到它没有使用 C#。
            【解决方案10】:

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

            var namesCount = (int)MyEnum.Length;
            

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

            【讨论】:

            • 这也依赖于从 0 开始的枚举(默认值,但绝不保证)。此外,它使正常枚举使用的智能感知非常令人困惑。这几乎总是一个可怕的想法。
            • 没多久 :)
            • 有趣,我想你永远不知道什么时候会有更好的事情发生。我尽我最大的努力回避自己的解决方案,但发现它很有趣,可以分享!
            • 可以说,如果您的用例使用以 0 开头的枚举,则此路由是性能最高的。但请不要称它为“长度”。我使用 COUNT,所以它在智能感知世界中脱颖而出。我也经常使用 ERROR 作为默认值,所以很明显,当在 pre 中没有设置某些东西时,一切都可以为空世界..
            猜你喜欢
            • 1970-01-01
            • 2010-11-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-08
            相关资源
            最近更新 更多