Tổng số mục được xác định trong một enum


318

Làm thế nào tôi có thể nhận được số lượng các mục được xác định trong một enum?

Câu trả lời:


430

Bạn có thể sử dụng phương thức tĩnh Enum.GetNamestrả về một mảng biểu thị tên của tất cả các mục trong enum. Thuộc tính độ dài của mảng này bằng với số lượng các mục được xác định trong enum

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

1
Đồng ý ... đây là một liên kết tôi tìm thấy csharp411.com/c-count-items-in-an-enum
Người dùng SO

8
Cũng có thể sử dụng Enum.GetValues.
Xonatron

6
System.Enum.GetNames, nếu bạn chưa bao gồm không gian tên Hệ thống.
Brett Pennings

4
Vì vậy, tôi chỉ gặp phải vấn đề này một lần nữa ngày hôm nay; Thủ thuật kiểu C như được mô tả trong các câu trả lời khác bên dưới được liệt kê là có vấn đề nhưng cả Enum.GetValues ​​và Enum.GetNames như được liệt kê ở trên có vẻ như họ có nguy cơ phân bổ một mảng hoàn toàn mới chỉ để có độ dài cố định, có vẻ như ... tốt , kinh khủng. Có ai biết nếu phương pháp này thực sự phát sinh phân bổ động? Nếu vậy, đối với các trường hợp sử dụng nhất định, nó dường như xa và là giải pháp hiệu quả nhất nếu không phải là linh hoạt nhất.
J Trana

174

Câu hỏi là:

Làm thế nào tôi có thể nhận được số lượng các mục được xác định trong một enum?

Số lượng "vật phẩm" thực sự có thể có nghĩa là hai thứ hoàn toàn khác nhau. Hãy xem xét ví dụ sau.

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

Số lượng "vật phẩm" được định nghĩa là MyEnumgì?

Là số lượng mục 5? ( A, B, C, D, E)

Hay là 3? ( 1, 2, 3)

Số lượng tên được xác định trong MyEnum(5) có thể được tính như sau.

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

Số lượng giá trị được xác định trong MyEnum(3) có thể được tính như sau.

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

2
Cách khác để viết dòng cuối cùng , var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();.
Jeppe Stig Nielsen

3
Tôi không thể nghĩ về bất kỳ nhà phát triển nào tôi từng gặp trong đời, người đã khẳng định rằng một enum như vậy có 3 mục.
motoDrizzt

2
@motoDrizzt bạn có thể tìm thấy một cái gì đó giống như vậy trong một enum của trình điều khiển máy in như Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;).
shA.t


14

Một mẹo tiện lợi mà tôi đã thấy trong câu trả lời C cho câu hỏi này, chỉ cần thêm một phần tử cuối cùng vào enum và sử dụng nó để cho biết có bao nhiêu phần tử trong enum:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

Trong trường hợp bạn đang xác định giá trị bắt đầu khác 0, bạn có thể sử dụng NumberOfTypes - Type1 để xác định số lượng phần tử.

Tôi không chắc liệu phương pháp này có nhanh hơn sử dụng Enum hay không và tôi cũng không chắc liệu nó có được coi là cách thích hợp để làm việc này hay không, vì chúng tôi có Enum để xác định thông tin này cho chúng tôi.


1
điều này thật tuyệt vì tôi có thể làm điều này trên XNA vì GetNames không có sẵn ở đó
Thiago Valle

Thủ thuật thú vị, điều này cũng sẽ nhanh hơn GetNames () vì nó không phải tính chúng.
Jordan LaPawn

4
Cảnh giác với mã chuyển qua enums thông qua foreach - bạn có thể đọc hết phần cuối của mảng!
Michael Dorgan

4
Ngoài ra, hãy cẩn thận với các enum xác định giá trị riêng của chúng - Tôi thường sử dụng các enum cho các cờ bit.
Matt Parkins

1
Ngoài ra, hãy cẩn thận với các ràng buộc enum trực tiếp với một số điều khiển wpf như combobox và listbox
mcy

6

Từ các câu trả lời trước chỉ cần thêm mẫu mã.

 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

Bạn có thể sử dụng Enum.GetNames để trả về vô số giá trị IE trong enum của bạn và sau đó. Đếm kết quả IEnumerable.

GetNames tạo ra nhiều kết quả tương tự như GetValues ​​nhưng nhanh hơn.


5

Nếu bạn thấy mình viết giải pháp trên thường xuyên như tôi thì bạn có thể thực hiện nó như một cách chung chung:

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

Tôi đã xem xét điều này ngay bây giờ, và không hài lòng với khả năng đọc của giải pháp hiện tại. Nếu bạn đang viết mã không chính thức hoặc trên một dự án nhỏ, bạn có thể thêm một mục khác vào cuối enum của bạn được gọi là "Độ dài". Bằng cách này, bạn chỉ cần gõ:

var namesCount = (int)MyEnum.Length;

Tất nhiên, nếu những người khác sẽ sử dụng mã của bạn - hoặc tôi chắc chắn trong nhiều trường hợp khác không áp dụng cho tôi trong trường hợp này - giải pháp này có thể là bất cứ nơi nào từ không được khuyên đến khủng khiếp.


2
Điều này cũng dựa vào enum bắt đầu từ 0 (mặc định, nhưng không có nghĩa là được bảo đảm). Ngoài ra, nó làm cho intellisense cho việc sử dụng enum bình thường rất khó hiểu. Đây gần như luôn là một ý tưởng khủng khiếp .
BradleyDotNET

2
Điều đó đã không mất nhiều thời gian :)
EnergyWasRaw

1
Thật thú vị, tôi cho rằng bạn không bao giờ biết khi nào điều gì tốt hơn có thể xảy ra. Tôi đã cố gắng hết sức để trốn tránh giải pháp của riêng mình, nhưng thấy nó đủ thú vị để chia sẻ!
EnergyWasRaw

1

Đối với Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthđã không làm việc với tôi, nhưng [Enum].GetNames(GetType(Animal_Type)).lengthđã làm.


Tại sao các downvote? Điều này đã khắc phục sự cố của tôi, đó là cú pháp chính xác cho VB, mặc dù câu hỏi được gắn thẻ c #, vẫn hữu ích.
M Granja

2
Downvote có thể vì câu hỏi được gắn thẻ C # và câu trả lời này không đề cập đến việc nó không sử dụng C #.
idbrii
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.