2009-05-13 4 views

ответ

304

Вы можете использовать статический метод Enum.GetNames, который возвращает массив, представляющий имена всех элементов в перечислении. Свойство длины этого массива равно числу элементов, определенных в перечислении

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

Согласен ... вот ссылка, которую я нашел http://www.csharp411.com/c-count-items-in-an-enum/ –

+5

Также можно использовать Enum.GetValues. – Xonatron

+0

System.Enum.GetNames, если вы еще не включили пространство имен System. –

67

Enum.GetValues (typeof (MyEnum)).

+2

Это быстрее использовать метод GetNames. –

+0

Должны ли кэшироваться результаты в классе утилиты? – djmj

+1

Я откатил это назад - в противном случае это всего лишь менее полезная версия принятого ответа. – Flexo

5

Вы можете использовать Enum.GetNames, чтобы возвращать IEnumerable значений в вашем перечислении и затем. Установить итоговый IEnumerable.

GetNames производит тот же результат, что и GetValues, но быстрее.

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

Изящный трюк, который я видел в С ответа на этот вопрос, просто добавить последний элемент перечисления и использовать его, чтобы сказать, сколько элементов в перечислении:

enum MyType { 
    Type1, 
    Type2, 
    Type3, 
    NumberOfTypes 
} 

В Если вы определяете начальное значение, отличное от 0, вы можете использовать NumberOfTypes - Type1 для определения количества элементов.

Я не уверен, что этот метод будет быстрее, чем использование Enum, и я также не уверен, что это будет считаться правильным способом, так как у нас есть Enum для выяснения этой информации для нас.

+0

это приятно, так как я могу сделать это на XNA, потому что GetNames там недоступно –

+0

Прохладный трюк, это также будет быстрее, чем GetNames(), потому что ему не нужно их подсчитывать. –

+3

Остерегайтесь кода, который проходит через enums через foreach - вы можете прочитать с конца своих массивов! –

140

Возникает вопрос:

Как я могу получить количество элементов, определенных в перечислении?

Число «предметов» действительно может означать две совершенно разные вещи. Рассмотрим следующий пример.

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) может быть вычислена следующим образом.

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

Число значений, определенных вMyEnum (3) может быть вычислена следующим образом.

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

Это должно быть проголосовано до вершины. – Xonatron

+1

Альтернативный способ записи последней строки, 'var valuesCount = ((MyEnum []) Enum.GetValues ​​(typeof (MyEnum))). Distinct(). Count();'. –

3

Для Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Length не работал со мной, но [Enum].GetNames(GetType(Animal_Type)).length сделал.

+0

Почему downvote? Это исправило мою проблему, это правильный синтаксис для VB, хотя вопрос отмечен C#, по-прежнему полезен. –

+0

Downvotes, вероятно, потому что вопрос отмечен C#, и в этом ответе не упоминалось, что он не использовал C#. – idbrii

-1

Я изучал это только сейчас и не был доволен читабельностью текущего решения. Если вы пишете текст неформально или в небольшом проекте, вы можете просто добавить еще один элемент в конец вашего перечисления под названием «Длина». Таким образом, вам нужно только ввести:

var namesCount = (int)MyEnum.Length; 

Конечно, если другие собираются использовать свой код - или я уверен, что при многих других обстоятельствах, которые не обращались ко мне в данном случае - это решение может быть в любом месте от плохого совета до ужасного.

+1

Это также зависит от перечисления, начинающегося с 0 (по умолчанию, но отнюдь не гарантированного). Кроме того, это делает intellisense для нормального использования перечисления * очень * запутанным. Это почти всегда ужасная идея. – BradleyDotNET

+1

Это не заняло много времени :) – EnergyWasRaw

+1

Интересно, я полагаю, вы никогда не знаете, когда может возникнуть что-то лучшее. Я сделал все возможное, чтобы отказаться от своего собственного решения, но нашел его достаточно интересным, чтобы поделиться! – EnergyWasRaw

2

Если вы обнаружили записи выше решение так часто, как я тогда вы могли бы реализовать его как родовое:

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