2011-08-20 30 views
6

Các MSDN documentation cho thuộc tính Flag nói rằng bạn nên:enums Cờ mà không cần sức mạnh của hai giá trị

Xác định hằng liệt kê trong quyền hạn của hai, đó là, 1, 2, 4, 8, và vân vân . Điều này có nghĩa là các cờ riêng lẻ trong việc liệt kê kết hợp hằng số không trùng lặp.

... và tất nhiên tôi luôn cố gắng nhớ điều đó. Tuy nhiên, không có gì thi hành điều đó và nếu bạn chỉ tạo một điều tra theo cách 'cơ bản' như ...

[Flags] 
public enum BrokenEnum 
{ 
    None, 
    FirstOption, 
    SecondOption, 
    ThirdOption 
} 

... nó sẽ không hoạt động như mong đợi. Để chống lại điều này, tôi đang tìm một số loại phân tích mã tĩnh (như FxCop) có thể cảnh báo tôi khi một enum giống như một cái ở trên tồn tại trong mã của tôi. Cảnh báo gần nhất mà tôi có thể tìm thấy là 'CA1008: Enums should have zero value' - cũng hữu ích khi thiết kế cờ liệt kê chính xác nhưng không đủ.

Cách tốt nhất để tìm các cờ được thiết kế không chính xác trong mã của tôi là gì? Giải pháp càng tự động càng tốt.

Trả lời

2

Như Jacob nói, nó có thể hữu ích để có hỗn hợp cờ ... nhưng có thể bạn có thể chỉ ra rằng bằng cách nào đó để phát hiện của bạn không nhớ. Nó không phải là quá khó để viết một bài kiểm tra đơn vị mà đi qua mọi enum trong một hội đồng trang trí với [Flags] và kiểm tra rằng có một giá trị cho 0 (có thể đảm bảo nó được gọi là None hoặc Default) và mọi giá trị được xác định khác (từ Enum.GetValues()) là một sức mạnh của hai. Bạn có thể kiểm tra xem sử dụng if ((x & (x - 1)) == 0).

Bạn có thể có thứ gì đó giống như thuộc tính [Combination] để chỉ ra giá trị được thiết kế để kết hợp ... thậm chí họ có thể chỉ ra tên cờ nào được kết hợp, vì vậy bạn cũng có thể kiểm tra.

Tôi biết điều này không phải là khá tốt như một kiểm tra thời gian biên dịch, nhưng giả sử bạn đã chạy thử nghiệm thường xuyên, nó khá gần.

+1

Tôi đoán tôi không nên nghĩ 'bên trong hộp' phân tích mã tĩnh. Một bài kiểm tra đơn vị như thế này khá dễ dàng và cho tôi kết quả gần như giống nhau. –

3

Đôi khi bạn muốn có một enum cờ đại diện cho nhiều tùy chọn; trong những trường hợp như vậy, đó không phải là lỗi. Dưới đây là ví dụ phổ biến:

[Flags] 
public enum FilePermissions 
{ 
    None = 0, 
    Read = 1, 
    Write = 2, 
    Execute = 4, 

    ReadWrite = 3, // Read | Write, 
    ReadWriteExecute = 7 // Read | Write | Execute 
} 

Có lẽ vì cần hỗ trợ các trường hợp như vậy, đó là lý do tại sao trình biên dịch không gây ra cảnh báo hoặc lỗi.

+0

Tôi có thể thấy lý do tại sao trình biên dịch không thực hiện điều đó (cũng nghĩ đến khả năng tương thích ngược, độ phức tạp không được điều chỉnh, v.v.) vì vậy tôi không sao nếu bạn không nhận được cảnh báo trình biên dịch. Nhưng tôi vẫn đang tìm cách để được cảnh báo. Trong các trường hợp như của bạn là việc sử dụng là hợp lệ, bạn có thể vô hiệu hóa việc kiểm tra với một cái gì đó giống như thuộc tính 'SuppressMessage'. –

+0

Bạn cũng có thể có nhiều cờ phức tạp hơn. Ví dụ '{View = 1, Alter = 2, Action = 4 | Xem | Alter} ': do đó hành động một mục bạn cần Xem và Thay đổi; ngoài chính nó. –

3

Tôi chưa bao giờ thử bản thân mình, nhưng có thể bạn có thể viết quy tắc tùy chỉnh cho FxCop.

Kiểm tra FxCop and Code Analysis: Writing Your Own Custom Rules.

+0

Cảm ơn, điều đó có vẻ rất hứa hẹn.Tôi có thể gắn bó với câu trả lời của Jon Skeet chỉ vì tôi nghĩ rằng nó sẽ nhanh hơn trong ngắn hạn để viết một bài kiểm tra đơn vị thay vì học cách viết một quy tắc FxCop tùy chỉnh. –

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