Загальна кількість елементів, визначених у перерахунку


Відповіді:


430

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

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

1
Погоджено ... ось посилання я знайшов csharp411.com/c-count-items-in-an-enum
користувач SO

8
Також можна використовувати Enum.GetValues.
Xonatron

6
System.Enum.GetNames, якщо ви ще не включаєте простору імен системи.
Бретт Пеннінгз

4
Тож я просто сьогодні знову стикався з цією проблемою; фокус у стилі C, як описано в інших відповідях нижче, вказаний як проблематичний, але обидва Enum.GetValues ​​та Enum.GetNames, як зазначено вище, здаються, вони ризикують виділити цілий новий масив просто для отримання фіксованої довжини, що здається ... ну , жахливий. Хтось знає, чи дійсно такий підхід має динамічне розподіл? Якщо так, то для певних випадків використання здається, що далеко і далеко не найефективніше рішення, якщо не найвигідніше.
J Trana

174

Питання:

Як я можу визначити кількість елементів, визначених у перерахунку?

Кількість "предметів" справді може означати дві абсолютно різні речі. Розглянемо наступний приклад.

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();

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

Вишуканий трюк, який я побачив у відповіді С на це запитання, просто додайте останній елемент до enum і використовуйте його, щоб сказати, скільки елементів у переліку:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

У випадку, коли ви визначаєте початкове значення, відмінне від 0, ви можете використовувати NumberOfTypes - Type1 для визначення кількості елементів.

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


1
це приємно, оскільки я можу це зробити на XNA, оскільки GetNames там недоступний
Thiago Valle

Класний трюк, це також буде швидше, ніж GetNames (), оскільки не потрібно їх рахувати.
Jordan LaPrise

4
Остерігайтеся коду, який циркулює через перерахунки через foreach - ви можете прочитати кінець своїх масивів!
Майкл Дорган

4
Також остерігайтеся переліків, які визначають власні значення - я часто використовую переписки для бітових прапорів.
Метт Паркінс

1
Також остерігайтеся прямих прив’язок перерахунків до деяких елементів керування wpf, таких як комбобокс та
список списків

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, щоб повернути IE численні значення у вашій enum, а потім .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

2
Це не зайняло багато часу
EnergyWasRaw

1
Цікаво, я думаю, ви ніколи не знаєте, коли може статися щось краще. Я зробив все можливе, щоб ухилитись від власного рішення, але мені було цікаво поділитися!
EnergyWasRaw

1

Для Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthне працював зі мною, але [Enum].GetNames(GetType(Animal_Type)).lengthробив.


Чому потік? Це вирішило мою проблему, це правильний синтаксис для VB, хоча питання позначено c #, все ще корисно.
M Granja

2
Зрозуміло, тому що питання позначено тегом C #, і ця відповідь не згадує, що він не використовує C #.
idbrii
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.