Całkowita liczba pozycji zdefiniowanych w wyliczeniu


Odpowiedzi:


430

Możesz użyć metody statycznej, Enum.GetNamesktóra zwraca tablicę reprezentującą nazwy wszystkich elementów w wyliczeniu. Właściwość length tej tablicy jest równa liczbie elementów zdefiniowanych w wyliczeniu

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

1
Zgadzam się ... oto link znalazłem csharp411.com/c-count-items-in-an-enum
— SO Użytkownik

8
Można również użyć Enum.GetValues.
— Xonatron,

6
System.Enum.GetNames, jeśli jeszcze nie uwzględniono przestrzeni nazw System.
— Brett Pennings

4
Właśnie dzisiaj znów spotkałem się z tym problemem; sztuczka w stylu C opisana w innych odpowiedziach poniżej jest wymieniona jako problematyczna, ale zarówno Enum.GetValues, jak i Enum.GetNames wymienione powyżej wydają się ryzykować przydzielenie całej nowej tablicy tylko po to, aby uzyskać stałą długość, która wydaje się ... no cóż. , okropny. Czy ktoś wie, czy to podejście rzeczywiście pociąga za sobą dynamiczną alokację? Jeśli tak, w niektórych przypadkach użycia wydaje się to najbardziej wydajnym rozwiązaniem, jeśli nie najbardziej elastycznym.
— J Trana,

174

Pytanie brzmi:

Jak mogę uzyskać liczbę elementów zdefiniowanych w wyliczeniu?

Liczba „przedmiotów” może naprawdę oznaczać dwie zupełnie różne rzeczy. Rozważ następujący przykład.

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

Jaka jest liczba „przedmiotów” zdefiniowanych w MyEnum?

Czy liczba pozycji wynosi 5? ( A, B, C, D, E)

Czy to jest 3? ( 1, 2, 3)

Liczbę nazw zdefiniowanych w MyEnum(5) można obliczyć w następujący sposób.

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

Liczbę wartości zdefiniowanych w MyEnum(3) można obliczyć w następujący sposób.

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

2
Alternatywnym sposobem pisania ostatniej linii var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();.
— Jeppe Stig Nielsen

3
Nie mogę wymyślić żadnego programisty, którego spotkałem w życiu, który potwierdziłby, że taki wyliczenie zawiera 3 elementy.
— motoDrizzt,

2
@motoDrizzt można znaleźć coś takiego w wyliczeniu sterownika drukarki, takiego jak Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;).
— shA.t


14

Sprytna sztuczka, którą widziałem w odpowiedzi C na to pytanie, po prostu dodaj ostatni element do wyliczenia i użyj go, aby powiedzieć, ile elementów jest w tym wyliczeniu:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

W przypadku, gdy definiujesz wartość początkową inną niż 0, możesz użyć NumberOfTypes - Type1, aby ustalić liczbę elementów.

Nie jestem pewien, czy ta metoda byłaby szybsza niż używanie Enum, a także nie jestem pewien, czy uznano by to za właściwy sposób, aby to zrobić, ponieważ mamy Enum do sprawdzenia dla nas tych informacji.


1
jest to miłe, ponieważ mogę to zrobić na XNA, ponieważ GetNames nie jest tam dostępne
— Thiago Valle

Fajna sztuczka, byłoby to również szybsze niż GetNames (), ponieważ nie trzeba ich liczyć.
— Jordan LaPrise

4
Uważaj na kod, który cyklicznie przechodzi przez wyliczenia przez foreach - możesz odczytać koniec swoich tablic!
— Michael Dorgan

4
Uważaj też na wyliczenia, które definiują własne wartości - często używam wyliczeń do flag bitowych.
— Matt Parkins

1
Uważaj również na bezpośrednie powiązania enum z niektórymi kontrolkami wpf, takimi jak combobox i listbox
— mcy

6

Z poprzednich odpowiedzi po prostu dodałem przykładowy kod.

 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

Możesz użyć Enum.GetNames, aby zwrócić IEnumerable wartości w twoim enum, a następnie .Count wynikowy IEnumerable.

GetNames daje taki sam wynik jak GetValues, ale jest szybszy.


5

Jeśli zauważysz, że piszesz powyższe rozwiązanie tak często jak ja, możesz zaimplementować je jako ogólne:

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

Właśnie się tym zajmowałem i nie byłem zadowolony z czytelności obecnego rozwiązania. Jeśli piszesz kod nieformalnie lub w małym projekcie, możesz po prostu dodać kolejny element na końcu wyliczenia o nazwie „Długość”. W ten sposób wystarczy wpisać:

var namesCount = (int)MyEnum.Length;

Oczywiście, jeśli inni zamierzają użyć twojego kodu - lub jestem pewien, że w wielu innych okolicznościach, które nie dotyczyły mnie w tym przypadku - to rozwiązanie może być gdziekolwiek, od złej porady po straszne.


2
Zależy to również od wyliczenia rozpoczynającego się od 0 (domyślnie, ale w żadnym wypadku nie jest gwarantowane). Dodatkowo sprawia, że ​​intellisense do normalnego używania enum jest bardzo mylące. To prawie zawsze okropny pomysł.
— BradleyDotNET

2
Nie trwało to długo :)
— EnergyWasRaw

1
Interesujące, przypuszczam, że nigdy nie wiadomo, kiedy może powstać coś lepszego. Zrobiłem co w mojej mocy, by odrzucić moje własne rozwiązanie, ale uznałem to za wystarczająco interesujące, aby się nim podzielić!
— EnergyWasRaw

1

W przypadku Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthnie działało ze mną, ale działało [Enum].GetNames(GetType(Animal_Type)).length.


Dlaczego głosowanie negatywne? To rozwiązało mój problem, jest to poprawna składnia dla VB, mimo że pytanie jest oznaczone jako c #, nadal przydatne.
— M Granja,

2
Zanotowano prawdopodobnie dlatego, że pytanie jest oznaczone jako C #, a ta odpowiedź nie wspomniała, że ​​nie używa C #.
— idbrii
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.