2009-07-27 41 views
32

Tôi có một combo box nơi tôi đang trưng bày một số mục như:String để chuyển đổi enum trong C#

Equals 
Not Equals 
Less Than 
Greater Than 

Chú ý rằng những chuỗi chứa khoảng trắng. Tôi có một điều kiện xác định phù hợp với các mục nhập này như:

enum Operation{Equals, Not_Equals, Less_Than, Greater_Than}; 

Vì không được phép, tôi đã sử dụng ký tự _.

Bây giờ, có cách nào để chuyển đổi chuỗi đã cho tự động thành phần tử enum mà không cần viết vòng lặp hay tập hợp các điều kiện tự của tôi trong C# không?

+0

liên quan mạnh mẽ: [how-to-set-space-on-enum] (http://stackoverflow.com/questions/1101872/how-to-set-space-on-enum) – nawfal

+1

Ngoài từ điển tiếp cận bên dưới, bạn có thể sử dụng các thuộc tính để kết hợp siêu dữ liệu (như chuỗi hiển thị) với một enum. Kiểm tra [Các ins and outs của C# enums] (http://www.codeducky.org/ins-outs-c-enums/). – ChaseMedallion

Trả lời

67

Tôi đề xuất xây dựng một Dictionary<string, Operation> để ánh xạ các tên thân thiện với các hằng số enum và sử dụng các quy ước đặt tên thông thường trong chính các phần tử đó.

enum Operation{ Equals, NotEquals, LessThan, GreaterThan }; 

var dict = new Dictionary<string, Operation> { 
    { "Equals", Operation.Equals }, 
    { "Not Equals", Operation.NotEquals }, 
    { "Less Than", Operation.LessThan }, 
    { "Greater Than", Operation.GreaterThan } 
}; 

var op = dict[str]; 

Ngoài ra, nếu bạn muốn gắn bó với phương pháp hiện tại của bạn, bạn có thể làm (mà tôi khuyên không nên làm):

var op = (Operation)Enum.Parse(typeof(Operation), str.Replace(' ', '_')); 
+1

Không quan tâm, tại sao bạn khuyên bạn nên sử dụng Enum.Parse? nhiều chuyển đổi hơn? – Pondidum

+15

Tôi không chống lại phương pháp 'Enum.Parse'. Tôi chống lại các chuỗi giao diện người dùng khớp nối chặt chẽ với các phần tử mã (và thay đổi mã theo tên hiển thị). –

18

Hoặc tạo ra một mapper chuyên dụng sử dụng một cuốn từ điển (mỗi câu trả lời Mehrdad của) hoặc triển khai TypeConverter.

Biến tùy chỉnh TypeConverter của bạn có thể thay thế " " -> "_" (và ngược lại) hoặc nó có thể phản ánh điều tra và sử dụng thuộc tính để xác định văn bản hiển thị của mục.

enum Operation 
{ 
    [DisplayName("Equals")] 
    Equals, 

    [DisplayName("Not Equals")] 
    Not_Equals, 

    [DisplayName("Less Than")] 
    Less_Than, 

    [DisplayName("Greater Than")] 
    Greater_Than 
}; 

public class OperationTypeConverter : TypeConverter 
{ 
    private static Dictionary<string, Operation> operationMap; 

    static OperationTypeConverter() 
    { 
     BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.GetField 
      | BindingFlags.Public; 

     operationMap = enumType.GetFields(bindingFlags).ToDictionary(
      c => GetDisplayName(c) 
      ); 
    } 

    private static string GetDisplayName(FieldInfo field, Type enumType) 
    { 
     DisplayNameAttribute attr = (DisplayNameAttribute)Attribute.GetCustomAttribute(typeof(DisplayNameAttribute)); 

     return (attr != null) ? attr.DisplayName : field.Name; 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     string stringValue = value as string; 

     if (stringValue != null) 
     { 
      Operation operation; 
      if (operationMap.TryGetValue(stringValue, out operation)) 
      { 
       return operation; 
      } 
      else 
      { 
       throw new ArgumentException("Cannot convert '" + stringValue + "' to Operation"); 
      } 
     } 
    } 
} 

thực hiện Điều này có thể được cải thiện bằng nhiều cách:

  • Làm cho nó chung
  • Thực hiện ConvertTo
  • Hỗ trợ FlagsAttribute
+0

Dường như có cái gì đó bị thiếu ... enumType không bao giờ được khai báo, GetDisplayName đang gọi với một tham số nhưng có 2 tham số được khai báo. –

+0

Chỉnh sửa: enumType không bao giờ được khai báo trong hàm tạo static –

+4

cũng không xuất hiện mà bạn có thể sử dụng thuộc tính DisplayName trên khai báo enum –

19
Operation enumVal = (Operation)Enum.Parse(typeof(Operation), "Equals") 

Đối với "Không Equals", bạn obv cần phải r không gian eplace với dấu gạch trong tuyên bố trên

EDIT: Phiên bản sau thay thế không gian với dấu gạch trước khi thực hiện các phân tích cú pháp:

string someInputText; 
var operation = (Operation)Enum.Parse(typeof(Operation), someInputText.Replace(" ", "_")); 
+0

Điều đó sẽ không khớp với "Không bằng" với Operation.Not_Equals –

+0

Đó là whay tôi đã nói bạn cần phải thay thế giá trị để thay thế dấu cách bằng dấu gạch dưới để nó khớp với ... – AdaTheDev

9

Bạn có thể sử dụng phương thức Parse:

Operarion operation = (Operation)Enum.Parse(typeof(Operation), "Not_Equals"); 

Một số ví dụ here

0

Tại sao lại sử dụng cách khác: chuyển đổi liệt kê thành chuỗi?

Chỉ cần tạo các mục của hộp tổ hợp từ liệt kê của bạn.

0

trong C#, bạn có thể thêm các phương thức mở rộng vào loại enum. Xem http://msdn.microsoft.com/en-us/library/bb383974.aspx

Bạn có thể sử dụng phương pháp này để thêm phương thức toString (Operation op), fromString (String str) và toLocalizedString (Operation op) vào loại enum của bạn.Phương pháp mà bạn sử dụng để tra cứu chuỗi cụ thể tùy thuộc vào ứng dụng của bạn và phải nhất quán với những gì bạn làm trong các trường hợp tương tự. Sử dụng từ điển như những người khác đã đề xuất có vẻ như là một phương pháp tiếp cận đầu tiên tốt miễn là bạn không cần bản địa hóa đầy đủ trong ứng dụng của mình.

0

Tôi sẽ sử dụng một singleton này enum mapper class thực hiện nhanh hơn Enum.Parse (sử dụng phản chiếu và thực sự chậm). Sau đó, bạn có thể sử dụng EnumFromString(typeof(YourEnum), "stringValue") để nhận được enum của mình.

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