Gesamtzahl der in einer Aufzählung definierten Elemente


318

Wie kann ich die Anzahl der in einer Aufzählung definierten Elemente ermitteln?

Antworten:


430

Sie können die statische Methode verwenden, Enum.GetNamesdie ein Array zurückgibt, das die Namen aller Elemente in der Aufzählung darstellt. Die Längeneigenschaft dieses Arrays entspricht der Anzahl der in der Aufzählung definierten Elemente

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

1
Einverstanden ... hier ist ein Link, den ich gefunden habe csharp411.com/c-count-items-in-an-enum
SO User

8
Könnte auch Enum.GetValues ​​verwenden.
Xonatron

6
System.Enum.GetNames, wenn Sie den System-Namespace noch nicht enthalten.
Brett Pennings

4
Also bin ich heute wieder auf dieses Problem gestoßen; Der Trick im C-Stil, wie in anderen Antworten unten beschrieben, wird als problematisch aufgeführt, aber sowohl die oben aufgeführten Enum.GetValues ​​als auch die Enum.GetNames scheinen das Risiko einzugehen, ein ganz neues Array zuzuweisen, nur um eine feste Länge zu erhalten, was ... gut scheint , schrecklich. Weiß jemand, ob dieser Ansatz tatsächlich eine dynamische Zuordnung erfordert? Wenn ja, scheint es für bestimmte Anwendungsfälle bei weitem die leistungsfähigste Lösung zu sein, wenn nicht die flexibelste.
J Trana

174

Die Frage ist:

Wie kann ich die Anzahl der in einer Aufzählung definierten Elemente ermitteln?

Die Anzahl der "Gegenstände" könnte wirklich zwei völlig verschiedene Dinge bedeuten. Betrachten Sie das folgende Beispiel.

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

Wie viele "Elemente" sind in definiert? MyEnum ?

Ist die Anzahl der Artikel 5? ( A, B, C, D,E )

Oder ist es 3? ( 1, 2, 3)

Die Anzahl der in (5) definierten NamenMyEnum kann wie folgt berechnet werden.

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

Die Anzahl der in (3) definierten WerteMyEnum kann wie folgt berechnet werden.

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

2
Alternative Art, die letzte Zeile zu schreiben , var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();.
Jeppe Stig Nielsen

3
Ich kann mir keinen Entwickler vorstellen, den ich jemals in meinem Leben getroffen habe und der behaupten würde, dass eine solche Aufzählung 3 Elemente enthält.
MotoDrizzt

2
@motoDrizzt finden Sie so etwas in einer Aufzählung eines Druckertreibers wie Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;).
shA.t

Sollte die akzeptierte Antwort sein
nilskober


14

Ein geschickter Trick, den ich in einer C-Antwort auf diese Frage gesehen habe. Fügen Sie der Aufzählung einfach ein letztes Element hinzu und verwenden Sie es, um festzustellen, wie viele Elemente sich in der Aufzählung befinden:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

Wenn Sie einen anderen Startwert als 0 definieren, können Sie mit NumberOfTypes - Type1 die Anzahl der Elemente ermitteln.

Ich bin mir nicht sicher, ob diese Methode schneller ist als die Verwendung von Enum, und ich bin mir auch nicht sicher, ob dies als der richtige Weg angesehen wird, da wir Enum haben, um diese Informationen für uns zu ermitteln.


1
Das ist schön, da ich dies auf XNA tun kann, weil GetNames dort nicht verfügbar ist
Thiago Valle

Cooler Trick, das wäre auch schneller als GetNames (), weil es sie nicht zählen muss.
Jordan LaPrise

4
Hüten Sie sich vor Code, der Enums über foreach durchläuft - Sie können das Ende Ihrer Arrays ablesen!
Michael Dorgan

4
Achten Sie auch auf Aufzählungen, die ihre eigenen Werte definieren. Ich verwende häufig Aufzählungen für Bit-Flags.
Matt Parkins

1
Achten Sie auch auf direkte Enum-Bindungen an einige wpf-Steuerelemente wie Combobox und Listbox
mcy

6

Aus den vorherigen Antworten nur Codebeispiel hinzufügen.

 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

Sie können Enum.GetNames verwenden, um eine IEnumerable von Werten in Ihrer Enum zurückzugeben, und dann .Count die resultierende IEnumerable.

GetNames liefert fast das gleiche Ergebnis wie GetValues, ist jedoch schneller.


5

Wenn Sie feststellen, dass Sie die obige Lösung so oft schreiben wie ich, können Sie sie generisch implementieren:

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

Ich habe mich gerade damit befasst und war mit der Lesbarkeit der aktuellen Lösung nicht zufrieden. Wenn Sie informell oder in einem kleinen Projekt Code schreiben, können Sie am Ende Ihrer Aufzählung einfach ein weiteres Element mit dem Namen "Länge" hinzufügen. Auf diese Weise müssen Sie nur Folgendes eingeben:

var namesCount = (int)MyEnum.Length;

Natürlich kann diese Lösung von schlecht beraten bis schrecklich sein, wenn andere Ihren Code verwenden - oder ich bin mir sicher, dass dies unter vielen anderen Umständen nicht auf mich zutrifft.


2
Dies hängt auch von der Aufzählung ab 0 ab (Standardeinstellung, jedoch keinesfalls garantiert). Darüber hinaus ist der Intellisense für die normale Verwendung von Enums sehr verwirrend. Das ist fast immer eine schreckliche Idee.
BradleyDotNET

2
Das hat nicht lange
gedauert

1
Interessant, ich nehme an, Sie wissen nie, wann etwas Besseres zustande kommen kann. Ich habe meinen besten Versuch unternommen, meine eigene Lösung zu meiden, fand sie aber interessant genug, um sie zu teilen!
EnergyWasRaw

1

Für Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthhat nicht mit mir gearbeitet, aber [Enum].GetNames(GetType(Animal_Type)).lengthgetan.


Warum das Downvote? Dies hat mein Problem behoben, es ist die richtige Syntax für VB, obwohl die Frage mit c # markiert ist, immer noch nützlich.
M Granja

2
Downvotes wahrscheinlich, weil die Frage mit C # markiert ist und in dieser Antwort nicht erwähnt wurde, dass C # nicht verwendet wurde.
idbrii
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.