列挙型で定義されたアイテムの総数


318

列挙型で定義されているアイテムの数を取得するにはどうすればよいですか?

回答:


430

Enum.GetNames列挙型のすべての項目の名前を表す配列を返す静的メソッドを使用できます。この配列の長さプロパティは、列挙型で定義されたアイテムの数と同じです

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

1
同意しました...ここに私が見つけたリンクがありますcsharp411.com/c-count-items-in-an-enum
SO User

8
Enum.GetValuesも使用できます。
Xonatron 2014年

6
System名前空間をまだ含めていない場合は、System.Enum.GetNames。
ブレットペニングス2015

4
だから今日もこの問題に遭遇しました。以下の他の回答で説明されているCスタイルのトリックは問題があるものとしてリストされていますが、上記のEnum.GetValuesとEnum.GetNamesの両方は、固定長を取得するためだけにまったく新しい配列を割り当てるリスクがあるようです... 、恐ろしい。このアプローチが実際に動的割り当てを引き起こすかどうか誰かが知っていますか?その場合、特定のユースケースでは、最も柔軟性が高くないとしても、最もパフォーマンスの高いソリューションは遠く離れているように見えます。
J Trana '19年

174

質問は:

列挙型で定義されているアイテムの数を取得するにはどうすればよいですか?

「アイテム」の数は、実際には2つのまったく異なるものを意味する可能性があります。次の例を考えてみましょう。

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

で定義されている「アイテム」の数はいくつMyEnumですか?

アイテムの数は5ですか?(ABCDE

それとも3ですか?(123

(5)で定義されている名前の数はMyEnum、次のように計算できます。

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

(3)で定義されたの数はMyEnum、次のように計算できます。

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

2
最後の行を書いている別の方法、var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();
Jeppe Stig Nielsen

3
私がこれまでに出会ったことのある開発者の中で、そのような列挙型に3つの項目が含まれていることを断言する人は思い当たりません。
motoDrizzt

2
@motoDrizzt Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;)のようなプリンタードライバーの列挙型でそのようなものを見つけることができます。
shA.t 2018


14

この質問に対するCの回答で見た気の利いたトリックは、最後の要素を列挙型に追加し、それを使用して列挙型内の要素の数を通知するだけです。

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

0以外の開始値を定義している場合は、NumberOfTypes-Type1を使用して要素の数を確認できます。

この方法がEnumを使用するよりも速いかどうかはわかりません。また、この情報を確認するためのEnumがあるため、これが適切な方法と見なされるかどうかもわかりません。


1
GetNamesが利用できないため、XNAでこれを行うことができるので、これは素晴らしいです
Thiago Valle

クールなトリックです。カウントする必要がないため、GetNames()よりも高速です。
ジョーダンラプリーズ2014

4
foreachを介して列挙型を循環するコードに注意してください-配列の終わりを読み取ることができます!
マイケルドーガン、2014年

4
また、独自の値を定義する列挙型にも注意してください。ビットフラグには列挙型を使用することがよくあります。
Matt Parkins、2015年

1
コンボボックスやリストボックスなどの一部のwpfコントロールへの直接列挙型バインディングにも注意してください
mcy

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を使用して、列挙型の値のIEnumerableを返し、結果のIEnumerableを.Countできます。

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

私は今これを調べていて、現在のソリューションの読みやすさに満足していませんでした。非公式または小規模なプロジェクトでコードを記述している場合は、「Length」と呼ばれる列挙型の末尾に別の項目を追加するだけで済みます。この方法では、次のように入力するだけです。

var namesCount = (int)MyEnum.Length;

もちろん、他の人があなたのコードを使用しようとしている場合-または、この場合私には当てはまらない他の多くの状況で確信している場合-この解決策は、悪いアドバイスからひどいところまであります。


2
これは、0から始まる列挙型にも依存します(デフォルトですが、決して保証されていません)。さらに、それは通常の列挙型の使用のためのインテリセンスを非常に混乱させます。これはほとんど常にひどい考えです。
BradleyDotNET

2
それは長くはかからなかった:)
EnergyWasRaw 2014年

1
興味深いことに、何か良いことがいつ発生するかは、あなたにはわからないでしょう。私は自分の解決策を回避しようと最善を尽くしましたが、共有するのに十分興味深いものでした!
EnergyWasRaw 2014年

1

Visual Basicの場合:

[Enum].GetNames(typeof(MyEnum)).Length私と一緒には機能しませんでしたが、機能しまし [Enum].GetNames(GetType(Animal_Type)).lengthた。


なぜ反対票か。これで私の問題は修正されました。質問にc#のタグが付けられていても、VBの正しい構文ですが、まだ役に立ちます。
M Granja

2
おそらく、質問にC#のタグが付けられており、この回答ではC#を使用していないことには言及しなかったため、反対票が投じられました。
idbrii
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.