2009-07-08 34 views
24

Kể từ khi liệt kê sử dụng số nguyên, những gì cấu trúc khác mà tôi có thể sử dụng để cung cấp cho tôi quyền truy cập enum giống như với giá trị gắn liền với tên:Liệt kê với kiểu trả về không phải là chuỗi?

[Tôi biết điều này là sai, tìm kiếm thay thế]

private enum Project 
    { 
     Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"), 
     Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"), 
     Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"), 
     Sales = new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435"), 
     Replacement = new Guid("11E5CBA2-EDDE-4ECA-BDFD-63BDBA725C8C"), 
     Modem = new Guid("6F686C73-504B-111-9A0B-850C26FDB25F"), 
     Audit = new Guid("30558C7-66D9-4189-9BD9-2B87D11190"), 
     Queries = new Guid("9985242-516A-4151-B7DD-851112F562") 
    } 

CHỈNH SỬA 2014-07-20

Đây là câu trả lời mới hơn cho câu hỏi này. Sử dụng lớp Attribute với một phương thức trợ giúp, xác định các thuộc tính phụ cần thiết trên enum của bạn.

public enum MultiValueEnum 
    { 
     [FooAttribute("alpha", 20d, true)] 
     First, 
     [FooAttribute("beta", 40.91d, false)] 
     Second, 
     [FooAttribute("gamma", 1.2d, false)] 
     Third, 
    }  

    public class FooAttribute : Attribute 
      { 
       internal FooAttribute(string name, double percentage, bool isGood) 
       { 
        this.Name = name; 
        this.Percentage = (decimal)percentage; 
        this.IsGood = isGood; 
       } 
       public string Name { get; private set; } 
       public decimal Percentage { get; private set; } 
       public bool IsGood { get; private set; } 
      } 



    public static TAttribute GetAttribute<TAttribute>(this Enum value) 
     where TAttribute : Attribute 
     { 
      var type = value.GetType(); 
      var name = Enum.GetName(type, value); 
      return type.GetField(name) 
       .GetCustomAttributes(false) 
       .OfType<TAttribute>() 
       .SingleOrDefault(); 
     } 

Mà làm cho nó dễ dàng này:

 MultiValueEnum enumVar = MultiValueEnum.First; 
     var enumStringValue = enumVar.GetAttribute<FooAttribute>().Name; 
     var enumValueDecimal = enumVar.GetAttribute<FooAttribute>().Percentage; 
     var enumBool = enumVar.GetAttribute<FooAttribute>().IsGood; 

Trả lời

22

Nếu không, bạn có thể tạo Thuộc tính tùy chỉnh cho enum, có thể giữ Hướng dẫn.

Something bên cạnh những dòng này:

class EnumGuid : Attribute 
{ 
    public Guid Guid; 

    public EnumGuid(string guid) 
    { 
     Guid = new Guid(guid); 
    } 
} 

Và sau đó bạn muốn sử dụng nó như vậy:

enum Project 
{ 
    [EnumGuid("2ED3164-BB48-499B-86C4-A2B1114BF1")] 
    Cleanup = 1, 
    [EnumGuid("39D31D4-28EC-4832-827B-A11129EB2")] 
    Maintenance = 2 
    // and so forth, notice the integer value isn't supposed to be used, 
    // it's merely there because not assigning any value is a performance overhead. 
} 

Và cuối cùng bạn có thể (tôi luôn luôn làm điều này) tạo ra một phần mở rộng để dễ dàng nhận được guid:

static Guid GetEnumGuid(this Enum e) 
{ 
    Type type = e.GetType(); 

    MemberInfo[] memInfo = type.GetMember(e.ToString()); 

    if (memInfo != null && memInfo.Length > 0) 
    { 
     object[] attrs = memInfo[0].GetCustomAttributes(typeof(EnumGuid),false); 
     if (attrs != null && attrs.Length > 0) 
      return ((EnumGuid)attrs[0]).Guid; 
    } 

    throw new ArgumentException("Enum " + e.ToString() + " has no EnumGuid defined!"); 
} 

Vì vậy, cuối cùng tất cả những gì bạn phải có với enums là:

Guid guid = Project.Cleanup.GetEnumGuid(); 

Tôi sử dụng phương pháp này để đính kèm mô tả vào enums, thường là các chuỗi dài hơn chứa khoảng trắng, do đó không thể được sử dụng làm tên.

+3

Giải pháp này sẽ không xây dựng cho tôi. Tuy nhiên, nếu bạn thay đổi hàm tạo trên EnumGuid để lấy chuỗi và sau đó tạo ra các guid từ chuỗi này nó sẽ. lớp công khai EnumGuid: Thuộc tính { công khai Guid Guid {get; bộ tư nhân; } công khai EnumGuid (Chuỗi s) { this.Guid = Guid.Parse (s); } } – Drauka

+0

Vâng, có vẻ như bạn phải sử dụng các kiểu nguyên thủy cho các nhà xây dựng enum, xem: http://stackoverflow.com/questions/25859094/an-attribute-argument-must-be-a-constant-expression-create- a-thuộc tính-của. Tuy nhiên như đã nêu bởi @ Druaka, chuyển đổi một chuỗi thành một Guid bên trong constructor và tất cả đều tốt. – puddinman13

11

Tôi đã nhìn thấy phương pháp này (struct) được sử dụng bởi cận âm để lưu trữ tên cột và bảng.

internal struct Project 
{ 
    public static Guid Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); 
    public static Guid Maintenance = new Guid("39D31D4-28EC-4832-827B-A129EB2"); 
    public static Guid Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"); 
    public static Guid Sales = new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435"); 
    public static Guid Replacement = new Guid("11E5CBA2-EDDE-4ECA-BD63-B725C8C"); 
    public static Guid Modem = new Guid("6F686C73-504B-111-9A0B-850C26FDB25F"); 
    public static Guid Audit = new Guid("30558C7-66D9-4189-9BD9-2B87D11190"); 
    public static Guid Queries = new Guid("9985242-516A-4151-B7DD-851112F562"); 
} 

EDIT: - Cảm ơn bạn đã nhận xét về sự thiếu sót trong mã. Ở vị trí đầu tiên, nó sẽ biên dịch nếu chuỗi Guid không hợp lệ. Đối với không tạo ra các trường hợp để truy cập các biến có họ cần phải public static

+1

Không thể truy cập các trường riêng tư trong cấu trúc, cũng không thể khởi tạo các trường như bạn làm trong cấu trúc. – leppie

+3

Chúng cũng cần phải tĩnh, ví dụ để làm việc. – leppie

+0

Bạn không thể tạo các thể hiện của cấu trúc này, vì nó chỉ hoạt động như một vùng chứa –

0

Khi phải đối mặt với loại vấn đề tôi đã sử dụng cấu trúc với consts như các thành viên công cộng:

public struct FileExtensions 
{ 
    public const string ProcessingExtension = ".lck"; 
    public const string ProcessedExtension = ".xml"; 
    public const string FailedExtension = ".failed"; 
    public const string CsvExtension = ".csv"; 
} 
+1

Một lớp học sẽ có ý nghĩa hơn, cho bạn có thể lấy được từ nó, và mở rộng các hằng số. – leppie

+0

Tôi sẽ không lấy được từ một lớp học mà chỉ có mục đích là chứa các giá trị không đổi, vì đa hình sẽ không có ý nghĩa nhiều. Thay vào đó, tôi sẽ tiếp tục thêm các hằng số liên quan vào cùng một lớp, hoặc tạo các hằng số mới cho các tập hợp các hằng số mới. –

+0

@enrico: có một vài lợi ích, như trường cha mẹ nằm trong phạm vi. – leppie

0

Bạn có thể tạo một lớp tĩnh chỉ chứa các giá trị không đổi. Ví dụ:

internal static class Project 
{ 
    public static readonly Guid Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); 
    public static readonly Guid Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"); 
    public static readonly Guid Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"); 
} 

Bằng cách này, lớp hành vi đơn giản như là một container và đối tượng không thể được tạo ra từ nó.

Trong VB này sẽ là một mô-đun:

Friend Module Project 
    Public Shared ReadOnly Cleanup As Guid = New Guid("2ED3164-BB48-499B-86C4-A2B1114BF1") 
    Public Shared ReadOnly Maintenance As Guid = New Guid("39D31D4-28EC-4832-827B-A11129EB2") 
    Public Shared ReadOnly Upgrade As Guid = New Guid("892F865-E38D-46D7-809A-49510111C1") 
End Module 
+1

Guid cant be const .... – leppie

+1

Bạn nói đúng, tôi đã đổi chúng thành các trường chỉ đọc –

+0

Ở đây chúng tôi vẫn tiếp tục. Các lớp tĩnh không thể có các thành viên cá thể! – leppie

0

Kiểu enum có thể only support các integral types (trừ char) là giá trị của nó. Tuy nhiên, bạn có thể sử dụng một cái gì đó giống như một từ điển để tra cứu một tên cho một giá trị.

Dictionary<Guid> lookup = new Dictionary<Guid>(); 
lookup["Cleanup"] = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); 
lookup["Maintenance"] = new Guid("39D31D4-28EC-4832-827B-A11129EB2"); 
lookup["Upgrade"] = new Guid("892F865-E38D-46D7-809A-49510111C1"); 
// etc... 

Một cách khác là có một chuỗi giá trị chỉ đọc trong lớp tĩnh.

public static class Guids 
{ 
    public static readonly Guid Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"), 
    public static readonly Guid Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"), 
    public static readonly Guid Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"), 
} 
+0

Ở đây chúng tôi lại tiếp tục. Các lớp tĩnh không thể có các thành viên cá thể! – leppie

+0

Điểm tốt, cảm ơn. Cập nhật – heavyd

5

Tôi có thể đi theo tuyến đường từ điển trên trang này. Có một bảng tra cứu về cơ bản:

public class GuidMapper 
{ 
    private Dictionary<GuidTypes, Guid> mGuidMap = new Dictionary<GuidTypes, Guid>(); 
    public enum GuidTypes: int 
    { 
     Cleanup, 
     Maintenance, 
     Upgrade, 
     Sales, 
     Replacement, 
     Modem, 
     Audit, 
     Queries 
    } 

    public GuidMapper() 
    { 
     mGuidMap.Add(GuidTypes.Cleanup, new Guid("2ED31640-BB48-499B-86C4-A2B1114BF100")); 
     mGuidMap.Add(GuidTypes.Maintenance, new Guid("39D31D40-28EC-4832-827B-A11129EB2000")); 
     mGuidMap.Add(GuidTypes.Upgrade, new Guid("892F8650-E38D-46D7-809A-49510111C100")); 
     mGuidMap.Add(GuidTypes.Sales, new Guid("A5690E70-1111-4AFB-B44D-1DF3AD66D435")); 
     mGuidMap.Add(GuidTypes.Replacement, new Guid("11E5CBA2-EDDE-4ECA-BDFD-63BDBA725C8C")); 
     mGuidMap.Add(GuidTypes.Modem, new Guid("6F686C73-504B-1110-9A0B-850C26FDB25F")); 
     mGuidMap.Add(GuidTypes.Audit, new Guid("30558C70-66D9-4189-9BD9-2B87D1119000")); 
     mGuidMap.Add(GuidTypes.Queries, new Guid("99852420-516A-4151-B7DD-851112F56200")); 
    } 

    public Guid GetGuid(GuidTypes guidType) 
    { 
     if (mGuidMap.ContainsKey(guidType)) 
     { 
      return mGuidMap[guidType]; 
     } 
     return Guid.Empty; 
    } 
} 
2

Nếu bạn cần thích hợp enum giống như ngữ nghĩa và an toàn loại thì bạn có thể sử dụng mẫu như thế này.

(Bạn có thể xác thịt thêm nếu bạn cần thêm tính năng như nhà khai thác chuyển đổi, GetUnderlyingType, ToString v.v. Nếu bạn muốn sử dụng lại mẫu này cho nhiều lớp khác nhau. vào một lớp cơ sở trừu tượng, chung chung.)

Project x = Project.Cleanup; 
Project y = Project.Cleanup; 
Project z = Project.Maintenance; 

Console.WriteLine(x == y);  // True 
Console.WriteLine(x == z);  // False 
Console.WriteLine(x.Value); // 47801daa-7437-4bfe-a240-9f7c583018a4 

// this line will cause a compiler error 
Console.WriteLine(x == new Guid("47801daa-7437-4bfe-a240-9f7c583018a4")); 

// ... 

public class Project 
{ 
    private Project(Guid v) { Value = v; } 
    public Guid Value { get; private set; } 

    public static readonly Project Cleanup = 
     new Project(new Guid("47801daa-7437-4bfe-a240-9f7c583018a4")); 

    public static readonly Project Maintenence = 
     new Project(new Guid("2548a7f3-7bf4-4533-a6c1-dcbcfcdc26a5")); 

    public static readonly Project Upgrade = 
     new Project(new Guid("ed3c3e73-8e6a-4c09-84ae-7f0876d194aa")); 
} 
Các vấn đề liên quan