Total jumlah item yang didefinisikan dalam enum

318

Bagaimana saya bisa mendapatkan jumlah item yang didefinisikan dalam enum?

JADI Pengguna
sumber

Jawaban:

430

Anda bisa menggunakan metode statis Enum.GetNamesyang mengembalikan array yang mewakili nama-nama semua item di enum. Properti panjang array ini sama dengan jumlah item yang didefinisikan dalam enum

var myEnumMemberCount = Enum.GetNames(typeof(MyEnum)).Length;
Kasper Holdum
sumber
1
Setuju ... inilah tautan yang saya temukan csharp411.com/c-count-items-in-an-enum
SO Pengguna
8
Bisa juga menggunakan Enum.GetValues.
Xonatron
6
System.Enum.GetNames, jika Anda belum memasukkan System namespace.
Brett Pennings
4
Jadi saya hanya mengalami masalah ini lagi hari ini; Trik gaya C seperti dijelaskan dalam jawaban lain di bawah ini terdaftar sebagai bermasalah tetapi baik Enum.GetValues ​​dan Enum.GetNames seperti yang tercantum di atas tampak seperti mereka berisiko mengalokasikan seluruh array baru hanya untuk mendapatkan panjang yang tetap, yang tampaknya ... yah , mengerikan. Adakah yang tahu jika pendekatan ini memang menimbulkan alokasi dinamis? Jika demikian, untuk kasus penggunaan tertentu tampaknya solusi yang paling berkinerja jika bukan yang paling fleksibel.
J Trana
174

Pertanyaannya adalah:

Bagaimana saya bisa mendapatkan jumlah item yang didefinisikan dalam enum?

Jumlah "item" dapat benar-benar berarti dua hal yang sangat berbeda. Perhatikan contoh berikut.

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

Berapa jumlah "item" yang didefinisikan MyEnum?

Apakah jumlah item 5? ( A, B, C, D, E)

Atau 3? ( 1, 2, 3)

Jumlah nama yang didefinisikan dalam MyEnum(5) dapat dihitung sebagai berikut.

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

Jumlah nilai yang didefinisikan dalam MyEnum(3) dapat dihitung sebagai berikut.

var valuesCount = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Distinct().Count();
Perisai Timothy
sumber
2
Cara alternatif menulis baris terakhir var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();,.
Jeppe Stig Nielsen
3
Saya tidak dapat memikirkan pengembang apa pun yang pernah saya temui dalam hidup saya yang menegaskan bahwa enum seperti itu mengandung 3 item.
motoDrizzt
2
@ motoDrizzt Anda dapat menemukan sesuatu seperti itu di enum driver printer seperti Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;).
shA.t
72

Enum.GetValues (typeof (MyEnum)). Panjang;

Matt Hamilton
sumber
7
Lebih cepat menggunakan metode GetNames.
Kasper Holdum
Haruskah hasilnya di-cache dalam kelas utilitas?
djmj
14

Trik bagus yang saya lihat dalam jawaban C untuk pertanyaan ini, cukup tambahkan elemen terakhir ke enum dan gunakan untuk mengetahui berapa banyak elemen dalam enum:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

Dalam hal Anda menentukan nilai awal selain 0, Anda bisa menggunakan NumberOfTypes - Type1 untuk memastikan jumlah elemen.

Saya tidak yakin apakah metode ini akan lebih cepat daripada menggunakan Enum, dan saya juga tidak yakin apakah itu akan dianggap cara yang tepat untuk melakukan ini, karena kami memiliki Enum untuk memastikan informasi ini untuk kami.

Josh
sumber
1
ini bagus karena saya bisa melakukan ini di XNA karena GetNames tidak tersedia di sana
Thiago Valle
Trik keren, ini juga akan lebih cepat daripada GetNames () karena tidak harus menghitungnya.
Jordan LaPrise
4
Waspadalah terhadap kode yang menggilir enum melalui foreach - Anda dapat membaca akhir dari array Anda!
Michael Dorgan
4
Juga, waspadalah terhadap enum yang menentukan nilai mereka sendiri - saya sering menggunakan enums untuk flag bit.
Matt Parkins
1
Waspadai juga pengikatan enum langsung ke beberapa kontrol WPF seperti kotak kombo dan listbox
mcy
6

Dari jawaban sebelumnya hanya menambahkan contoh kode.

 class Program
    {
        static void Main(string[] args)
        {
            int enumlen = Enum.GetNames(typeof(myenum)).Length;
            Console.Write(enumlen);
            Console.Read();
        }
        public enum myenum
        {
            value1,
            value2
        }
    }
Jvanderh
sumber
5

Anda dapat menggunakan Enum.GetNames untuk mengembalikan nilai-nilai IEnumerable di enum Anda dan kemudian. Menghitung IEnumerable yang dihasilkan.

GetNames menghasilkan banyak hasil yang sama dengan GetValues ​​tetapi lebih cepat.

Lucas Willett
sumber
5

Jika Anda menemukan diri Anda menulis solusi di atas sesering yang saya lakukan maka Anda dapat mengimplementasikannya sebagai generik:

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;
}
Matt Parkins
sumber
1

Saya sedang melihat ini sekarang, dan tidak senang dengan keterbacaan solusi saat ini. Jika Anda menulis kode secara informal atau pada proyek kecil, Anda bisa menambahkan item lain ke akhir enum Anda yang disebut "Panjang". Dengan cara ini, Anda hanya perlu mengetik:

var namesCount = (int)MyEnum.Length;

Tentu saja jika orang lain akan menggunakan kode Anda - atau saya yakin dalam banyak keadaan lain yang tidak berlaku untuk saya dalam kasus ini - solusi ini mungkin di mana saja dari sakit disarankan untuk mengerikan.

EnergyWasRaw
sumber
2
Ini juga bergantung pada enum mulai dari 0 (default, tetapi tidak berarti dijamin). Selain itu, itu membuat intellisense untuk penggunaan enum normal sangat membingungkan. Ini hampir selalu merupakan ide yang mengerikan .
BradleyDotNET
2
Itu tidak butuh waktu lama :)
EnergyWasRaw
1
Menarik, saya kira Anda tidak pernah tahu kapan sesuatu yang lebih baik bisa terjadi. Saya berusaha sebaik mungkin untuk menghindari solusi saya sendiri, tetapi merasa cukup menarik untuk dibagikan!
EnergyWasRaw
1

Untuk Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthtidak bekerja dengan saya, tetapi [Enum].GetNames(GetType(Animal_Type)).lengthberhasil.

S22
sumber
Mengapa downvote? Ini memperbaiki masalah saya, ini sintaks yang benar untuk VB, meskipun pertanyaannya ditandai c #, masih berguna.
M Granja
2
Downvotes mungkin karena pertanyaan ditandai C # dan jawaban ini tidak menyebutkan bahwa ia tidak menggunakan C #.
idbrii