2010-04-30 25 views
12

Tôi đã viết mã số TryParse enum theo giá trị hoặc theo tên của nó như được hiển thị bên dưới. Làm thế nào tôi có thể mở rộng mã này để bao gồm phân tích cú pháp enums với thuộc tính Flags?Enum.TryParse với thuộc tính Flags

public static bool TryParse<T>(this T enum_type, object value, out T result) 
       where T : struct 
      { 
       return enum_type.TryParse<T>(value, true, out result); 
      } 



public static bool TryParse<T>(this T enum_type, 
object value, bool ignoreCase, out T result) 
     where T : struct 
    { 
     result = default(T); 
     var is_converted = false; 

     var is_valid_value_for_conversion = new Func<T, object, bool, bool>[]{ 
      (e, v, i) => e.GetType().IsEnum, 
      (e, v, i) => v != null, 
      (e, v, i) => Enum.GetNames(e.GetType()).Any(n => String.Compare(n, v.ToString(), i) == 0) || Enum.IsDefined(e.GetType(), v) 
     }; 

     if(is_valid_value_for_conversion.All(rule => rule(enum_type, value, ignoreCase))){ 
      result = (T)Enum.Parse(typeof(T), value.ToString(), ignoreCase); 
      is_converted = true; 
     } 

     return is_converted; 
    } 

Hiện nay mã này làm việc cho enums sau:

enum SomeEnum{ A, B, C } 
// can parse either by 'A' or 'a' 

enum SomeEnum1 : int { A = 1, B = 2, C = 3 } 
// can parse either by 'A' or 'a' or 1 or "1" 

Không làm việc cho:

[Flags] 
enum SomeEnum2 { A = 1, B = 2, C = 4 } // can parse either by 'A' or 'a' 
// cannot parse for A|B 

Cảm ơn!

Trả lời

0

@ câu trả lời Pop đã quyết định cho tôi một đầu mối & tôi sửa đổi các quy tắc kiểm tra trong mã của tôi trông giống như:

var is_valid_value_for_conversion = new Func<T, object, bool, bool>[] 
{ 
    (e, v, i) => e.GetType().IsEnum, 
    (e, v, i) => value != null, 
    (e, v, i) => Enum.GetNames(e.GetType()).Any(
       n => String.Compare(n, v.ToString(), i) == 0 
       || (v.ToString().Contains(",") && v.ToString().ToLower().Contains(n.ToLower()))) 
       || Enum.IsDefined(e.GetType(), v) 
}; 

phần còn lại còn lại giống nhau và nó làm việc cho tôi

HTH người khác

+1

Không nên kiểm tra null là quy tắc đầu tiên của bạn? – ChaosPandion

+0

Kiểm tra đầu tiên hoặc thứ hai sẽ không tạo sự khác biệt trong trường hợp này IMO, trừ khi tôi thiếu thứ gì đó, bên cạnh đó ràng buộc là cấu trúc, tôi nghĩ chúng ta cần kiểm tra xem cuộc gọi có thuộc loại enum hợp lệ hay không trước khi kiểm tra xem giá trị có vô giá trị – Sunny

16

Kể từ .NET 4, có phương thức Enum.TryParse<T>. Nó hỗ trợ Flags enumerations out of the box:

string x = (SomeEnum2.A | SomeEnum2.B).ToString(); // x == "A, B" 
SomeEnum2 y; 
bool success = Enum.TryParse<SomeEnum2>(x, out y); // y == A|B 
+7

có TryParse được tiếp xúc trong 4.0, tôi đang tìm kiếm một giải pháp trong 3,5 ... – Sunny

+0

tại sao không chỉ cần sử dụng Enum.Parse và wra p một khối try/catch xung quanh nó? – yoyo

26

Flags enums được viết bằng , bằng cách sử dụng quy ước Net và không |. Enum.Parse() hoạt động hoàn hảo khi sử dụng '' chuỗi:

[Flags] 
public enum Flags 
{ 
    A = 1, 
    B = 2, 
    C = 4, 
    D = 8, 
} 

var enumString = (Flags.A | Flags.B | Flags.C).ToString(); 
Console.WriteLine(enumString); // Outputs: A, B, C 
Flags f = (Flags)Enum.Parse(typeof(Flags), enumString); 
Console.WriteLine(f); // Outputs: A, B, C 
Các vấn đề liên quan