2012-09-07 43 views
10

Có rất nhiều câu hỏi ở đây về việc chuyển đổi chuỗi thành giá trị enum. Nói chung, câu trả lời trông giống như những câu trả lời trên this question:Tại sao đối tượng Enum.Parse() trả lại?

StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true); 

Trong khi đó là một câu trả lời hoàn toàn hợp lý, và bạn có thể viết một phương pháp để đơn giản hóa cuộc gọi, nó không trả lời câu hỏi của tại sao Enum. Phân tích cú pháp() trả về một số object thay vì giá trị enum thích hợp. Tại sao tôi phải truyền nó đến StatusEnum?


Edit:

Về cơ bản, câu hỏi là tại sao là một chức năng như thế này không nằm trong lớp Enum?

public static T Parse<T>(string value) where T: struct 
    { 
     return (T)Enum.Parse(typeof (T), value); 
    } 

Chức năng này hoạt động hoàn toàn tốt, thực hiện chính xác những gì bạn mong đợi. StatusEnum e = Enum.Parse<StatusEnum>("Active");.

+1

@ SpYk3HH - Enums không * có * giá trị. Chúng * là * giá trị. Chúng là những giá trị xảy ra có quá tải thông thường cho '.ToString()', nhưng chúng vẫn chỉ là giá trị. – Bobson

+2

.NET 4.0+ có ['Enum.TryParse '] (http://msdn.microsoft.com/en-us/library/dd783499 (v = vs.100)) –

+0

@ SpYk3HH giá trị của kiểu enum là một số số nguyên có thể được liên kết với một trong các trường của loại enum. Kích thước của số nguyên có thể thay đổi. Parse lấy một số chuỗi và trả về một thể hiện được đóng hộp của kiểu enum. Điều đó có thể được unboxed hay không. Câu cuối cùng của bạn cũng không có ý nghĩa gì cả. String và Boolean cũng có các thuộc tính và phương thức để làm việc. – phoog

Trả lời

10

Nó làm điều này vì

  1. Nó có trước Generics và (ngay cả khi nó đã không :)
  2. chế Generic không thể đếm (trong ngôn ngữ chủ đạo NET)

Như vậy, Object là loại duy nhất luôn hoạt động đối với bất kỳ loại enum nào.

Bằng cách trả về đối tượng, API ít nhất là chức năng, ngay cả khi yêu cầu truyền.

+1

Trong khi bạn không thể nói 'where t: Enum' bạn có thể nói' where t: struct' và ít nhất loại bỏ các kiểu tham chiếu, hoặc đặt không ràng buộc và tránh cast/typeof. – Guvante

+0

Thực tế là nó generated predics không phải là một explination. Nó sẽ là một thay đổi không phá vỡ để thêm hàm tôi đã chỉnh sửa ở trên làm quá tải cho kiểu cũ 'Enum.Parse()'. – Bobson

+0

@Reed - Hãy suy nghĩ về nó, theo logic của bạn, Enum.TryParse () không nên tồn tại, nhưng nó có. – Bobson

1

Loại thực tế của đối tượng thực sự là StatusEnum. Trình biên dịch và mã, khi viết Enum.Parse không có ý tưởng về đối tượng thời gian chạy đó sẽ là gì tại thời điểm phương thức được viết. Nó sẽ không được biết đến cho đến khi phương thức này thực sự được gọi. Tuy nhiên

3

TryParse không hỗ trợ một số loại:

Enum.TryParse<FooEnum>(name, true, out ret);

Do đó, nếu bạn chỉ định các giá trị ret ra như FooEnum ret;, bạn sẽ không cần phải bỏ nó vào một FooEnum sau đó; nó sẽ thuộc loại thích hợp ngay lập tức.

+0

Đó là sự thật, nhưng bây giờ bạn cần hai dòng mã. Có thể là ba. Một tuyên bố 'ret', cái này và một cái để sử dụng nó mà bạn có thể không cần thiết. Vì vậy, nâng cao câu hỏi về lý do tại sao có một dạng chung của 'TryParse()' và không phải là một dạng chung của 'Parse()'. – Bobson

+0

Nó có lẽ chỉ bị bỏ qua. Bạn có thể làm cho quá tải chung chung của bạn như là một phương pháp mở rộng khá dễ dàng mặc dù. – aevitas

+0

Thực ra, bạn không thể. Bạn không thể mở rộng 'Enum', bởi vì nó là một lớp tĩnh. Vì vậy, bạn sẽ được gọi là 'EnumExtensions.Parse()' (hoặc bất cứ điều gì bạn gọi là lớp học của bạn), và sẽ không có lợi ích để trở thành một phương pháp mở rộng. – Bobson

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