2012-07-31 40 views
8

Có ai có giải pháp thanh lịch hơn để phân tích cú pháp enums không? Sau đây chỉ có vẻ như một mớ hỗn độn với tôi.Phân tích thành công C# Enums

UserType userType = (UserType)Enum.Parse(typeof(UserType), iUserType.ToString()); 

Trả lời

13

tôi thường làm một helper generic cho nó:

public static T ParseEnum<T>(string value) where T:struct 
{ 
    return (T)Enum.Parse(typeof(T), value); 
} 

Bạn có thể kết hợp điều đó với Jon Skeet'sUnstrained Melody (hoặc bất kỳ bộ xử lý bài IL khác) để có được một loại hạn chế thích hợp trên một enum, nhưng điều đó Là tùy chọn.

Sau đó, bạn có thể sử dụng nó như thế này:

var enumValue = ParseEnum<UserType>(iUserType.ToString()); 

.NET Framework 4.0 cũng đi kèm với Enum.TryParse mà còn cung cấp một cú pháp tương tự, và cung cấp một cách để xử lý nếu phân tích thất bại. Ví dụ:

UserType userType; 
if (Enum.TryParse<UserType>(iUserType.ToString(), out userType)) 
{ 
    //Yay! Parse succeeded. The userType variable has the value. 
} 
else 
{ 
    //Oh noes! The parse failed! 
} 
+0

Tôi nhận thấy rằng đối với Enum.TryParse(), việc phân tích cú pháp không bao giờ thất bại, mặc dù tôi muốn nó cho các giá trị không nằm trong enum. Ví dụ của tôi là tại: https://pastebin.com/fZfT69Lk – Colin

+0

@Colin - thú vị. Điều này là bởi vì một giá trị số nguyên luôn luôn chuyển đổi thành một enum, ví dụ '(TestEnum) 4737373' hoạt động và biên dịch, quá. Nếu bạn muốn thực thi rằng giá trị của bạn là một giá trị được đặt tên, bạn có thể sử dụng GetNames để đảm bảo giá trị của nó ở đó. – vcsjones

3

Bạn có thể tạo một phương pháp extesion như thế này

public static class EnumExtensions 
{ 
    public static T ToEnum<T>(this string s) 
    { 
     return (T)Enum.Parse(typeof(T), s); 
    } 
} 

sau đó trong mã bạn có thể sử dụng nó theo cách này (MyEnum chứa các giá trị A và B):

string s = "B"; 
MyEnum e = s.ToEnum<MyEnum>(); 
1

Đây là một phương pháp mở rộng dựa trên phiên bản và phản hồi @vcsjones và từ ví dụ @Mones:

public enum TestEnum 
{ 
    None, 
    A, 
    B, 
}; 

void Main() 
{ 
    var testValues = new List<object>(); 
    testValues.AddRange(Enumerable.Range(-2, 6).Select(i => (object)i)); 
    testValues.AddRange(new List<string>() { String.Empty, "A", "B", "C", null }); 

    foreach (var testValue in testValues) 
    { 
     Console.WriteLine($"Testing value {testValue ?? String.Empty}:"); 
     TestEnum output; 
     var enumValues = Enum.GetNames(typeof(TestEnum)).ToList(); 
     try 
     { 
      if (TestEnum.TryParse(testValue.ToString(), out output)) 
      { 
       Console.WriteLine($"Succeeded with TryParse on {testValue} to {output}"); 
      } 
      else 
      { 
       Console.WriteLine($"Failed to TryParse on {testValue}"); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine($"Test harness caught an exception: {ex.ToString()}"); 
     } 

     var toEnumOutput = (testValue ?? String.Empty).ToString().Parse<TestEnum>(); 
     Console.WriteLine($"Parse<TEnum> returned {toEnumOutput}"); 

     Console.WriteLine(); 
     Console.WriteLine(); 
    } 

} 


public static class EnumExtensions 
{ 
    public static TEnum Parse<TEnum>(this string value) where TEnum : struct 
    { 
     TEnum output = default(TEnum); 
     var enumValues = Enum.GetNames(typeof(TEnum)).ToList(); 

     if (Enum.TryParse<TEnum>(value, true, out output)) 
      if (Enum.IsDefined(typeof(TEnum), value) || value.ToString().Contains(",") || enumValues.Contains(output.ToString())) 
      { 
       Console.WriteLine($"Converted '{value}' to {output}."); 
       return output; 
      } 
      else 
      { 
       Console.WriteLine($"{value} is not an underlying value of the enumeration."); 
      } 
     else 
     { 
      Console.WriteLine($"{value} is not a member of the enumeration."); 
     } 
     return default(TEnum); 
    } 
} 

Các khai thác thử nghiệm cho kết quả này:

Testing value -2: 
Succeeded with TryParse on -2 to -2 
-2 is not an underlying value of the enumeration. 
Parse<TEnum> returned None 


Testing value -1: 
Succeeded with TryParse on -1 to -1 
-1 is not an underlying value of the enumeration. 
Parse<TEnum> returned None 


Testing value 0: 
Succeeded with TryParse on 0 to None 
Converted '0' to None. 
Parse<TEnum> returned None 


Testing value 1: 
Succeeded with TryParse on 1 to A 
Converted '1' to A. 
Parse<TEnum> returned A 


Testing value 2: 
Succeeded with TryParse on 2 to B 
Converted '2' to B. 
Parse<TEnum> returned B 


Testing value 3: 
Succeeded with TryParse on 3 to 3 
3 is not an underlying value of the enumeration. 
Parse<TEnum> returned None 


Testing value : 
Failed to TryParse on 
is not a member of the enumeration. 
Parse<TEnum> returned None 


Testing value A: 
Succeeded with TryParse on A to A 
Converted 'A' to A. 
Parse<TEnum> returned A 


Testing value B: 
Succeeded with TryParse on B to B 
Converted 'B' to B. 
Parse<TEnum> returned B 


Testing value C: 
Failed to TryParse on C 
C is not a member of the enumeration. 
Parse<TEnum> returned None 


Testing value : 
Test harness caught an exception: System.NullReferenceException: Object reference not set to an instance of an object. 
    at UserQuery.Main() in C:\Users\Colin\AppData\Local\Temp\3\LINQPad5\_zhvrhwll\query_ludjga.cs:line 49 
is not a member of the enumeration. 
Parse<TEnum> returned None 

Tài liệu tham khảo:

+1

Tôi thấy bạn đã làm việc chăm chỉ để tạo ra một câu trả lời được nghiên cứu tốt với một bộ kiểm tra tốt đẹp. Điều đó thực sự tuyệt vời, nhưng hãy để tôi khuyến khích bạn thử sử dụng một số khung kiểm thử đơn vị. Bất kỳ ai, chúng thực sự giống những năm này. Tôi bị cám dỗ để viết lại bài kiểm tra của bạn với ** xUnit ** (Tôi thực sự thích điều đó, chỉ cần liên kết một nuget và tắt bạn đi) để cho bạn thấy nó có thể đọc được hay không, nhưng .. có lẽ bạn sẽ được hưởng lợi nhiều hơn tự mình làm. Thả cho tôi một tin nhắn nếu bạn muốn thử và bị mắc kẹt trên một cái gì đó. – quetzalcoatl

+0

Hi @quetzalcoatl - đánh giá cao phản hồi.Tôi thêm các bài kiểm tra nUnit và sau đó đăng một liên kết đến lớp kiểm tra của tôi. – Colin

0

Oh Tôi đã xem qua Tyler Brinkley của 012.thư viện mà thực hiện điều này và nhiều hơn nữa!

Câu trả lời StackOverflow khác Generic version of Enum.Parse in C# dẫn đến trang web thư viện Unconstrained Melody của Jon Skeet, nơi chúng tôi hướng dẫn Enums.NET thay thế. Wow.