2012-02-17 35 views
6

Với mã này:Enum.GetValues ​​(typeof (....)) không trả lại enum đúng giá trị

public enum Enum1 
{ 
    ONE, 
    TWO 
} 

public enum Enum2 
{ 
    A, 
    B 
} 

Mã này trả về một, hai:

foreach (Enum1 e in Enum.GetValues(typeof(Enum1))) 
{ 
    Console.WriteLine(e); 
} 

Nhưng mã này, thay vì thất bại (vì Enum2 e được sử dụng với typeof(Enum1)), trả về A, B:

foreach (Enum2 e in Enum.GetValues(typeof(Enum1))) 
{ 
    Console.WriteLine(e); 
} 

Tại sao vậy?

Trả lời

9

Bởi vì dưới bìa Enums chỉ là ints - thứ hai trả về giá trị Enum1, nhưng thực sự những giá trị đó chỉ là 01. Khi bạn truyền các giá trị đó vào loại Enum2, các giá trị này vẫn hợp lệ và tương ứng với các giá trị "A" và "B".

+1

Tất nhiên là họ ... Silly me! Tôi quên rằng trong C# enums thực sự là ints ưa thích.Tôi đã được sử dụng nhiều hơn để enums của Java đó là các lớp học đầy đủ chính thức. Buồn rằng trình biên dịch không bắt nó mặc dù ... – JohnDoDo

+6

@ JohnDoDo: Trình biên dịch không bắt được nó bởi vì "foreach (Enum2 e ..." thực hiện chuyển đổi ** rõ ràng ** - một diễn viên, hiệu quả - từ loại bộ sưu tập cho loại biến vòng lặp. Nó là hợp pháp để * cast * '(Enum2) enum1', và vì vậy nó là hợp pháp để làm điều tương tự ngầm với một * foreach *. Hãy nhớ, foreach được phát minh trước khi Generics, nếu bạn có một ArrayList của chuỗi, bạn muốn có thể nói 'foreach (string s trong myArrayList)' và có chuyển đổi rõ ràng được thực hiện tự động –

3

Khi bạn sử dụng Enum.GetValues(), nó trả về các giá trị cơ bản. Khi bạn sử dụng foreach(Type...), nó sẽ chuyển thành loại enum. Vì vậy, trong khi chúng có thể không phải là cùng một Enum, chúng có cùng giá trị cơ bản mà không có vấn đề gì.

gì đang xảy ra trong tương đương với này

int value = Enum.GetValues(typeof(Enum2))[1]; // this isn't valid code, it's more simplified 
Enum1 casted = (Enum1)value; 
8

Bởi vì các giá trị của sự đếm của bạn đang ngầm số nguyên:

public enum Enum1 
{ 
    ONE = 0, 
    TWO = 1 
} 

public enum Enum2 
{ 
    A = 0, 
    B = 1 
} 

Các giá trị của Enum1 đang được ngầm chuyển đổi sang số nguyên và sau đó đến các giá trị của Enum2. Nếu bạn định nghĩa lại Enum1 như sau ...

public enum Enum1 
{ 
    ONE = 0, 
    TWO = 1, 
    THREE = 2, 
} 

... sau đó nó sẽ thất bại không quay trở lại "A, B", vì không có giá trị trong Enum2 cho giá trị số nguyên 2

+1

Giá trị enum bắt đầu bằng 0, và thực sự in 'A, B, 2' thay vì thất bại - xem [Đúc ints vào enums trong C#] (http://stackoverflow.com/questions/1758321/casting-ints-to-enums-in-c-sharp) – Justin

+0

@Justin cố định, cảm ơn. –

1

Có là một diễn viên tiềm ẩn ở đây từ Enum1 -> int và int -> Enum2.

0

Lý do cho điều này là các enums có khả năng cast rõ ràng tới System.Int (giả sử chúng là int enums, theo mặc định).

Thứ hai của bạn foreach sau đó rõ ràng là đúc kết quả của Enum.GetValues(typeof(Enum1)) đến Enum2.

2

Enum.GetValues(typeof(Enum1)) trở lại {0,1} và foreach sẽ liệt kê trong phạm vi này

1

tôi sẽ đoán một người như Jon Skeet có thể đến ở đây và hoàn toàn giải thích những gì đang xảy ra tốt hơn so với tôi, nhưng mã này:

foreach (Enum2 e in Enum.GetValues(typeof(Enum1))) 
{ 
    Console.WriteLine(e); 
} 

... đang xem tất cả các giá trị Enum1 của bạn là Enum2 loại.

Vì loại dữ liệu enum giống như loại dữ liệu int, giá trị số của bạn từ Enum1 đang được sử dụng để lập chỉ mục Enum2.

Các vấn đề liên quan