2012-04-23 31 views
8

Thay vì tách từng quyền thành các cột riêng lẻ hoặc bảng máy chủ sql, chúng tôi đang xem xét lại việc sử dụng thuộc tính Flag để Enum để sử dụng với các hoạt động khôn ngoan. Ứng dụng của chúng tôi xác định điểm cuối (không phải là điểm từ dịch vụ nghỉ) để truy cập tài nguyên (đọc, sửa đổi, cập nhật) và mỗi người dùng được hưởng quyền truy cập ví dụ Bob has permissions to Read, Modify resource X vì vậy khi bob đến và truy cập tài nguyên này, chúng tôi kiểm tra xem liệu bob có quyền x.Now hay không rằng nơi chúng ta sẽ áp dụng điều này là rõ ràng đây là sự nghi ngờ của tôiEnums để xác định các bộ quyền trong C#

  • Giả sử Bob có đọc, Viết, Xóa phép về tài nguyên sử dụng enumerations được gắn cờ tôi sẽ làm Permission.Read | Permission.Write | Permission.Delete là kết quả cuối cùng của chút khôn ngoan và một nguyên hoặc Enum khác?

  • Để lưu trữ quyền này trong bảng cơ sở dữ liệu, cột có phải là integer không?

  • Nếu câu trả lời cho câu hỏi 1 là Enum thì tôi có nên xác định một thuộc tính khác trên Permissions enum đại diện cho giá trị nguyên của Bit khôn ngoan và hoạt động không?

disclaimer: Bob được đề cập trong ví dụ này không đại diện cho bất kỳ người dùng nào trong mạng tràn của trang web hoặc bất kỳ người nào. Nó chỉ là một ký tự khác

Trả lời

10

Để trả lời câu hỏi của bạn theo thứ tự:

  • Giả sử bạn đã thiết lập các thuộc tính [Flags] trên enum, và sử dụng các nhà điều hành chính xác (&| cho các hoạt động Bitwise) nó về cơ bản là cả hai. Nếu bạn đưa kết quả vào một số nguyên, bạn sẽ nhận được bitwise và các giá trị có liên quan, ví dụ: 7 cho ví dụ của bạn. Nếu bạn sử dụng .ToString(), thì bạn sẽ nhận được một chuỗi trở lại cho biết rằng giá trị có tất cả ba giá trị.Tôi tin rằng có một phương pháp HasFlags() nơi nào đó, nhưng hầu hết các mã tôi đã thấy sử dụng mã cố gắng và đúng Bitwise để so sánh, ví dụ:

    var x = Permissions.Read | Permissions.Write; 
    if ((x & Permissions.Read) == Permissions.Read) { print "Success!"; } 
    

    Từ một quan điểm kỹ thuật, C# 's loại an toàn giúp giữ cho mọi thứ lành mạnh và kết quả của | ing hoặc & ing hai enum s cùng loại là một enum cùng loại nhưng tất cả enum s đơn giản là số nguyên và có thể được xử lý như vậy trong hầu hết các trường hợp, mặc dù một số điều cần rõ ràng phôi đến/từ int.

  • Nó phải là một loại tích phân, có. Tôi tin rằng loại mặc định cho một enum là Int32, tuy nhiên bạn có thể thiết lập rõ ràng nếu bạn muốn kết hợp cơ sở dữ liệu và mã chính xác.

  • Với tất cả những điều trên, bạn vẫn có thể có nhiều ý nghĩa để có các giá trị được xác định trước cho các nhóm quyền được sử dụng thường xuyên, ví dụ ReadWrite. Đặc biệt, một phần tử None được đề xuất cho tất cả các enums của Microsoft, đặc biệt là nếu bạn sắp có giá trị truyền. Điều này cho phép dự phòng và giá trị hợp lệ cho các biến mới được khởi tạo cũng như giá trị sane cho default(Permissions). Bạn có thể đặt giá trị trong enum của bạn dựa trên những người khác như vậy:

    [Flags] 
    enum Permissions { 
        None = 0, 
        Read = 0x001, 
        Write = 0x010, 
        Execute = 0x100, 
        ReadWrite = Read | Write, 
        // [snip] 
    } 
    
+0

@Mathhew chỉ cần tắt đầu của tôi Lưu trữ kết quả của bitwise OR trong bảng như số nguyên. Làm thế nào tôi nên làm cho tôi kiểm tra sự cho phép trong ứng dụng. nói trong mã ở đây 'if (IntegerFromDb == Permissions.Read) {print" Success! "; } 'nên ** tôi phân tích cú pháp Integer thành Enum of type Permissions ** và thực hiện kiểm tra? – Deeptechtons

+0

@Deeptechtons: Bạn có thể truyền bất kỳ số nguyên nào trở lại kiểu enum một cách dễ dàng: 'var perms = (Permissions) IntegerFromDb'. Đây là cách an toàn nhất, tuy nhiên tôi nghĩ rằng bạn có thể so sánh trực tiếp với mã tôi đã đưa vào ở trên mà không cần một diễn viên. Luôn luôn so sánh '&' với giá trị mong đợi, đặc biệt nếu sử dụng các giá trị kết hợp như 'ReadWrite' được đề xuất bởi vì nó có thể có một và không phải là giá trị khác và đánh dấu kiểm tra kiểu'! = None'. –

+0

@Deeptechtons: Hãy nhớ đọc ghi chú của tôi ở điểm # 3 về giá trị sane cho enums. C# có thể chơi một cái gì đó khủng khiếp nếu bạn đúc một số nguyên để một enum mà không có ý nghĩa cho các giá trị nhất định. –

5
  1. Bitwise OR/VÀ cho giá trị của enum được đánh dấu bằng [Flags] là các giá trị của cùng một enum.
  2. Số nguyên được lưu trữ hợp lý để lưu trữ các giá trị enum trong cơ sở dữ liệu.
  3. Không, bạn không cần phải thêm các giá trị enum bổ sung, nhưng có thể làm như vậy cho conviniece.

Normaly bạn xác định sự đếm như vậy với FlagsAttribute ví dụ:

[Flags] enum My { 
    None = 0, Read =1, Write =2, Delete = 4 
}; 

Khi định nghĩa theo cách này, bạn có thể kết hợp các giá trị khác nhau với | (Hoặc) hoạt động:

My readAndWrite = My.Read | My.Write; 

Bitwise AND sẽ cung cấp cho bạn 0 cho các giá trị enum đại diện cho cờ độc đáo, nhưng thường được dùng để che giấu bit khác:

bool doIHaveWrite = (readAndWrite & My.Write) == My.Write; 

Lưu ý rằng logic AND (& &) có thể không được áp dụng cho các giá trị enum.

+2

+1 gọn gàng cậu cả đã giúp tôi Nếu có anyway tôi có thể đánh dấu cả hai như là câu trả lời, Gosh không có tính năng như vậy trên SO hiện nay. Tôi sẽ upvote bạn – Deeptechtons

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