2009-12-06 34 views
6

Tôi đang viết hàm có số Enum và chuyển nó thành uint. Từ những gì tôi đã nhìn thấy khi truyền tới int, trước tiên bạn phải truyền đến một đối tượng: (int) (object) myEnumValue. Nếu bạn viết (int) myEnumValue bạn sẽ nhận được một ngoại lệ thời gian biên dịch.Đúc Enum thành uint

Bây giờ, khi tôi cố gắng truyền nó sang uint, tôi đã mong rằng (uint) (object) myEnumValue sẽ không sao. Nó biên dịch độc đáo, nhưng khi chạy, nó tạo ra một InvalidCastException. Vì vậy, để làm cho nó hoạt động, tôi đã sử dụng

(uint) (int) (object) myEnumValue 

Tôi nghĩ có vẻ vui, vì vậy tôi khá vui, nhưng tại sao lại như vậy?

Có lẽ nó đã có chính xác hơn để hỏi tại sao nó không thể bỏ object để uint, nhưng tôi quan tâm đến việc liệu có một cách khác để đi từ một Enum để uint. Lanhung?

Edit:

Bối cảnh là một chức năng, một cái gì đó như thế này:

public static uint ToUInt (Enum e) 
{ 
    return (uint) (int) (object) e; 
} 

Sửa 2:

Giải pháp tốt nhất được nêu bởi thecoop:

Convert.ToUInt32(e) 

Trả lời

13

Cách tiếp cận (uint) (object) myEnum không thành công vì, theo mặc định, C# enums sử dụng int làm loại cơ bản của chúng và int là những gì chúng được chuyển thành khi chúng được đóng hộp. Cú pháp C# làm cho nó trông giống như enums kế thừa từ kiểu cơ bản của chúng (như enum MyEnum : uint).

Bạn phải nói rõ ràng trình biên dịch để Unbox từ object để int đầu tiên, sau đó làm một sự chuyển đổi số từ int để uint. (Mặc dù cú pháp là như nhau, unboxing từ object để một kiểu giá trị là một quá trình khác nhau từ đúc giữa intuint.)

+0

Ok, vì vậy nếu tôi chỉ định Enum là Enum: uint, nó sẽ là một cách khác? –

+0

@ Jonatan: vâng, điều đó sẽ đóng hộp enum như uint, và bạn sẽ bị buộc phải unbox như uint. –

+0

Đúng vậy: (uint) e sẽ ổn, nhưng (int) e sẽ phát nổ. –

5

Từ những gì tôi đã nhìn thấy khi đúc để int, bạn phải bỏ nó đối tượng đầu tiên: (int) (object) myEnum. Nếu bạn viết (int) myEnum bạn nhận được một ngoại lệ thời gian biên dịch.

Không đúng sự thật. Bạn có thể trực tiếp truyền một giá trị enum thành một kiểu số nguyên.

Bây giờ, khi tôi cố gắng truyền nó sang uint, tôi đã mong đợi rằng (uint) (đối tượng) myEnum sẽ không sao. Nó biên dịch độc đáo, nhưng khi chạy, nó tạo ra một InvalidCastException. Vì vậy, để có được nó để làm việc, tôi đã sử dụng: (uint) (int) (object) myEnum
Tôi nghĩ rằng nó trông buồn cười, vì vậy tôi khá hạnh phúc, nhưng tại sao nó như vậy?

Khi bạn cast một giá trị enum để object, nó sẽ được đóng hộp như cơ bản loại của nó, đó là int theo mặc định.Bạn không thể bỏ hộp giá trị được đóng hộp thành bất kỳ loại nào khác ngoài loại thực tế của nó trực tiếp. Ngay cả điều này sẽ thất bại:

short s = 10; 
object o = s; 
int i = (int)o; // throws `InvalidCastException` while `int i = (int)s;` works. 
0

Trong trường hợp bạn cần phải đi theo hướng ngược lại, có nghĩa là, từ một kiểu cơ bản cho đếm một loại đặc biệt:

enum MyEnumType { a, b, c }; 
//... 
MyEnumType enum_val = (MyEnumType)Enum.ToObject(typeof(MyEnumType), 2); 
Console.WriteLine(enum_val == MyEnumType.c); 
// "True" 

Tôi thấy điều này là cần thiết (chứ không phải là truyền đơn giản) khi tạo ra các loại generic. Vì bạn không thể sử dụng mệnh đề 'where' để hạn chế hoàn toàn loại <T> chung cho kiểu liệt kê của mình, trình biên dịch sẽ không cho phép bạn truyền một số tới nó.

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