2012-03-07 40 views
24

Tôi đang xây dựng một ứng dụng sử dụng số lượng lớn Enum giây cho dữ liệu tùy chỉnh. Về cơ bản, một đối tượng được lưu trữ trong cơ sở dữ liệu với khoảng 28 thuộc tính riêng biệt. Mỗi thuộc tính là một trường gồm hai ký tự được dịch từ SQL thẳng sang một số Enum.Thuộc tính tùy chỉnh cho Enums có nguy hiểm không?

Thật không may, tôi cũng cần dịch các giá trị này thành hai giá trị khác nhau có thể đọc được của con người. Một cho một chú giải trên một bảng dữ liệu, và một cho một lớp CSS để tạo kiểu cho một hình ảnh trên front-end ứng dụng web.

Để thực hiện việc này, tôi đã thiết lập hai thuộc tính tùy chỉnh và áp dụng chúng cho số Enum nếu cần. Ví dụ:

Tuỳ Thuộc tính Interface

public interface IAttribute<T> 
{ 
    T Value { get; } 
} 

Ví dụ Custom Attribute

public sealed class AbbreviationAttribute: Attribute, IAttribute<string> 
{ 
    private readonly string value; 

    public AbbreviationAttribute(string value) 
    { 
     this.value = value; 
    } 

    public string Value 
    { 
     get { return this.value; } 
    } 
} 

Phương pháp để lấy Custom Attribute từ Enum

public static R GetAttributeValue<T, R>(IConvertible @enum) 
{ 
    R attributeValue = default(R); 

    if (@enum != null) 
    { 
     FieldInfo fi = @enum.GetType().GetField(@enum.ToString()); 

     if (fi != null) 
     { 
      T[] attributes = fi.GetCustomAttributes(typeof(T), false) as T[]; 

      if (attributes != null && attributes.Length > 0) 
      { 
       IAttribute<R> attribute = attributes[0] as IAttribute<R>; 

       if (attribute != null) 
       { 
        attributeValue = attribute.Value; 
       } 
      } 
     } 
    } 

    return attributeValue; 
} 

Ví dụ Enum Sử dụng mẫu này

public enum Download 
{ 
    [Abbreviation("check")] 
    [Description("Certified")] 
    C = 1, 

    [Abbreviation("no-formal")] 
    [Description("No formal certification")] 
    NF = 2, 

    [Abbreviation("cert-prob")] 
    [Description("Certified with potential problems")] 
    CP = 3 
} 

Cả AbbreviationDescription là các thuộc tính tùy chỉnh mà thực hiện IAttribute<T>. Thực tế của tôi Enum có 11 giá trị có thể, và như tôi đã đề cập trước khi nó được sử dụng trong 28 thuộc tính riêng biệt trong đối tượng tùy chỉnh của tôi. Sử dụng các thuộc tính tùy chỉnh có vẻ là cách tốt nhất để ánh xạ thông tin này qua lại.

Bây giờ cho câu hỏi, đây có phải là cách tốt nhất để thực hiện việc này không? Tôi lưu trữ giá trị Enum ("C", "NF" hoặc "CP" trong đoạn mã trên) trong cơ sở dữ liệu, nhưng tôi cần giá trị của Viết tắt và Mô tả trong mã của tôi. Ngoài ra, tôi nghi ngờ đây sẽ là tập hợp các thuộc tính tùy chỉnh cuối cùng mà tôi cần.

Trước khi tiếp tục di chuyển về phía trước với mẫu này ... là cách phù hợp để thực hiện? Tôi muốn khắc phục các vấn đề tiềm năng với cách tiếp cận này ngay bây giờ hơn là phải theo dõi lại và tái cấu trúc sau này.

+2

Tôi có thể thấy một số vấn đề địa phương hóa vì nó đứng – asawyer

+0

Điểm tốt. Tôi có lẽ có thể sửa đổi 'IAttribute' để hỗ trợ thiết lập nội địa hóa kiểu' gettext'. Tôi quan tâm nhiều hơn đến khả năng mở rộng, hiệu suất và các phương pháp hay nhất mà tôi có thể không biết. – EAMann

+0

'GetAttributeValue' không phải là một phương pháp mở rộng trái với văn bản mô tả trước đó. –

Trả lời

13

Đây là phương pháp giống như tôi sử dụng. Nhược điểm là serialization. Các giá trị thuộc tính tùy chỉnh không tuần tự hóa.

Tôi thích phương pháp thuộc tính tùy chỉnh trên phương pháp cơ sở dữ liệu vì nó quan hệ dữ liệu thuộc tính quyền enum thay vì phải sử dụng một bảng tra cứu hoặc lớp vv

+1

Nhược điểm khác là bạn phải hoàn toàn triển khai lại ứng dụng nếu mô tả bao giờ thay đổi nhiều như một ký tự – eouw0o83hf

+1

@ eouw0o83hf: true. giảm nhẹ bởi các tùy chọn triển khai gần đây (aka ClickOnce), nhưng bạn là chính xác. Hầu hết các ứng dụng của tôi có xu hướng là web hoặc những thứ có thời gian dài giữa các chu kỳ triển khai, nơi nhiều thứ khác sẽ thay đổi, vì vậy việc cập nhật một vài mô tả không phải là vấn đề lớn. –

1

Bạn có thể thay đổi cơ sở dữ liệu không? Tôi nghĩ lựa chọn tốt nhất là tạo một bảng (hoặc bảng) để chứa các giá trị có thể của enums và khóa ngoài đối tượng chính trên nó (thay vì sử dụng mã char - điều này làm cho nó dễ dàng hơn và bình thường hóa DB của bạn) . Cung cấp cho bảng một cột AbbreviationDescription, sau đó kéo chúng vào và tham chiếu chúng bằng khóa của chúng và lưu chúng vào bộ đệm nếu tra cứu chậm.

Một điều nguy hiểm về các thuộc tính là nếu bất kỳ chuỗi nào trong số các chuỗi đó phải thay đổi, đó là một triển khai lại hoàn toàn của ứng dụng. Nếu bạn làm cho chúng giá trị cơ sở dữ liệu, bạn có thể thay đổi chúng với một đơn giản UPDATE.

2

tôi có lẽ muốn xây dựng một bảng băm và một loại đặc biệt cho một cái gì đó như thế này. Bạn có thể đã loại bỏ ý tưởng vì lý do nào đó hoặc lý do khác, nhưng đây là những gì tôi sẽ không biết các chi tiết cụ thể của ứng dụng của bạn.

class SpecialType { 
    // include the fields and all attributes that you need to reference, ToString method for debugging, and any serialization you need 
    public string foo { get; set; } 
    public string bar { get; set; } 
    public ToString() { return "SpecialType with foo '" + foo + "' and bar '" + bar + "'"; } 
} 

Dictionary<int, SpecialType> myDict = new Dictionary<int, SpecialType> { 
    { 1, new SpecialType { foo = "XA1B2", bar = "XC3D4" } }, 
    { 2, new SpecialType { foo = "ZA1B2", bar = "ZC3D4" } }, 
    { 3, new SpecialType { foo = "YA1B2", bar = "YC3D4" } }, 
} 

Sau đó, tôi có thể dễ dàng giữ ints trong các lớp học khác của tôi để tiết kiệm bộ nhớ, tìm hiểu xem một giá trị cụ thể là hợp lệ bằng cách kiểm tra sự tồn tại trong Keys của từ điển, tất cả những gì jazz. Nó có lẽ sẽ dễ dàng hơn nhiều để làm databinding nếu bạn cuối cùng sẽ sử dụng WPF hoặc đọc/ghi vào đĩa, quá.

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