2011-02-09 9 views
8

Tôi hiện đang đọc cuốn sách C# 4.0 in a Nutshell, theo cách tôi nghĩ là một cuốn sách tuyệt vời, ngay cả đối với những người lập trình nâng cao để sử dụng như một tài liệu tham khảo tốt.Enum.IsDefined với enum flagged

Tôi đã xem lại các chương về các khái niệm cơ bản, và tôi đã xem xét một mẹo để biết liệu một giá trị nào đó được xác định trong Enum khi sử dụng các enum được gắn cờ.
Cuốn sách khẳng định rằng việc sử dụng Enum.IsDefined không hoạt động trên enums gắn cờ, và đề nghị một công việc xung quanh như thế này:

static bool IsFlagDefined(Enum e) 
{ 
    decimal d; 
    return (!decimal.TryParse(e.ToString(), out d); 
} 

này sẽ trả về đúng nếu một giá trị nhất định được quy định tại một enum được gắn cờ.

Ai đó có thể giải thích cho tôi lý do tại sao tính năng này hoạt động không?

Cảm ơn trước :)

+0

là một trường hợp khác trong trường hợp Enum.IsDefined có thể hoạt động khác với dự kiến ​​(hoặc có thể là mặc định (T)). Enum.IsDefined (mặc định (T)) có thể trả về cả true và _false_. mặc định (T) (trong đó T là một enum) luôn luôn trả về (T) 0 vì vậy nếu T không có giá trị hợp lệ cho (T) 0 thì kết quả là sai. Đã hạ gục tôi ít nhất một lần –

Trả lời

12

Về cơ bản, gọi ToString trên bất kỳ giá trị enum của một loại tuyên bố với thuộc tính [Flags] sẽ trở lại một cái gì đó như thế này cho bất kỳ giá trị được xác định:

SomeValue, SomeOtherValue 

Mặt khác , nếu giá trị là không phải được xác định trong loại enum, thì ToString sẽ chỉ tạo ra một chuỗi đại diện cho giá trị đó là số nguyên giá trị, ví dụ .:

5 

Vì vậy, điều này có nghĩa là nếu bạn có thể phân tích đầu ra của ToString như một số (không chắc chắn lý do tại sao tác giả chọn decimal), nó không được định nghĩa trong vòng loại.

Dưới đây là một ví dụ:

[Flags] 
enum SomeEnum 
{ 
    SomeValue = 1, 
    SomeOtherValue = 2, 
    SomeFinalValue = 4 
} 

public class Program 
{ 
    public static void Main() 
    { 
     // This is defined. 
     SomeEnum x = SomeEnum.SomeOtherValue | SomeEnum.SomeFinalValue; 

     Console.WriteLine(x); 

     // This is not (no bitwise combination of 1, 2, and 4 will produce 8). 
     x = (SomeEnum)8; 

     Console.WriteLine(x); 
    } 
} 

Đầu ra của chương trình trên là:

 
SomeOtherValue, SomeFinalValue 
8 

Vì vậy, bạn có thể thấy phương pháp gợi ý hoạt động.

+0

Nên SomeEnum.SomeValue = 0? – PaulB

+0

@PaulB: Có thể. Bạn có hỏi vì thường có một giá trị 'None' cho 0? Điều đó đúng và có lẽ ít gây nhầm lẫn. Có lẽ tôi sẽ cập nhật câu trả lời chỉ để không ném bất cứ ai ra. –

+0

Có - chỉ rằng bạn không thể đại diện cho SomeValue với bất kỳ người nào khác ... Cảm ơn bạn đã thay đổi :) – PaulB

0

Nếu không thể tạo giá trị e bằng cách sử dụng kết hợp cờ ToString() mặc định là số nguyên. Và các số nguyên sẽ phân tích cú pháp của khóa học là decimal.

Nhưng tại sao mã của bạn phân tách dưới dạng thập phân không hoàn toàn rõ ràng đối với tôi. Nhưng có thể các loại tích phân sẽ không hoạt động đối với cả hai số enum s có trụ sở tại Int64UInt64.