2010-10-06 36 views
10

Giả sử enum:chuỗi Generic để enum chuyển đổi

public enum SysLogsAppTypes { None, MonitorService, MonitorTool }; 

và đây là một chức năng để chuyển đổi từ ToString() đại diện trở lại enum:

private SysLogsAppTypes Str2SysLogsAppTypes(string str) 
{ 
    try 
    { 
     SysLogsAppTypes res = (SysLogsAppTypes)Enum 
             .Parse(typeof(SysLogsAppTypes), str); 
     if (!Enum.IsDefined(typeof(SysLogsAppTypes), res)) 
      return SysLogsAppTypes.None; 
     return res; 
    } 
    catch 
    { 
    return SysLogsAppTypes.None; 
    } 
} 

Có cách nào để làm cho Generic này ??

tôi đã cố gắng:

private T Str2enum<T>(string str) 
{ 
    try 
    { 
     T res = (T)Enum.Parse(typeof(T), str); 
     if (!Enum.IsDefined(typeof(T), res)) return T.None; 
     return res; 
    } 
    catch 
    { 
     return T.None; 
    } 
} 

nhưng tôi nhận được: 'T' là một 'kiểu tham số', mà không phải là hợp lệ trong bối cảnh trao
nơi có T.None

Bất kỳ Cứu giúp ? Cảm ơn

+2

Chỉ cần thay thế 'mặc định (T) 'cho 'T.None' và bạn tốt để đi. – thecoop

Trả lời

10

Tôi nghĩ rằng từ khóa default là những gì bạn cần:

private T Str2enum<T>(string str) where T : struct 
{ 
    try 
    { 
     T res = (T)Enum.Parse(typeof(T), str); 
     if (!Enum.IsDefined(typeof(T), res)) return default(T); 
     return res; 
    } 
    catch 
    { 
     return default(T); 
    } 
} 
+5

Đây là câu trả lời đúng, nhưng điều quan trọng cần lưu ý là enum "mặc định" là bất kỳ giá trị nào được biểu diễn bằng 0. Đây thường là giá trị đầu tiên. Tuy nhiên, nếu enum của bạn bắt đầu từ 1, bạn sẽ trả về '0' thay vì bất kỳ giá trị pháp lý nào trong enum. Sử dụng phương pháp này sẽ yêu cầu báo trước cho hành vi này hoặc một số tiêu chuẩn mã hóa. Ví dụ, tôi đã thấy một số enums trong đó một giá trị 'NONE' là giá trị cuối cùng, mà sẽ không hoạt động trong phương thức này. –

4

Không cách bạn đang cố gắng nó, nhưng tôi sử dụng phương pháp dưới đây để làm điều này:

public static bool EnumTryParse<E>(string enumVal, out E resOut) 
     where E : struct 
{ 
     var enumValFxd = enumVal.Replace(' ', '_'); 
     if (Enum.IsDefined(typeof(E), enumValFxd)) 
     { 
      resOut = (E)Enum.Parse(typeof(E), 
      enumValFxd, true); 
      return true; 
     } 
     // ---------------------------------------- 
     foreach (var value in 
      Enum.GetNames(typeof (E)).Where(value => 
       value.Equals(enumValFxd, 
       StringComparison.OrdinalIgnoreCase))) 
     { 
      resOut = (E)Enum.Parse(typeof(E), value); 
      return true; 
     } 
     resOut = default(E); 
     return false; 
} 

Không có ngoại lệ ném ở đây ...

+1

Tôi thích giải pháp này. Tôi luôn luôn thích TryParse hơn giả định rằng các giá trị là hợp pháp. –

+0

+1 - Tôi thích mẫu 'TryParse', nhưng lưu ý: bằng cách thực hiện cuộc gọi phương thức' Enum.IsDefined' trước khi thử chuyển đổi, điều này sẽ không chuyển đổi các biểu diễn chuỗi của giá trị cơ bản của 'enum'. Đó là một lợi ích của 'try catch' và sau đó kiểm tra thuật toán' Enum.IsDefined'. Tôi cho rằng bạn có thể thực hiện 'int.TryParse' trước và thêm một trường hợp đặc biệt cho giải pháp trên. – jball

+0

@jball, bằng "biểu diễn chuỗi giá trị cơ bản", bạn có đang nói về, "1", "12", "một" hoặc "hai" hoặc "Hai mươi ba" không ?? –

2

Tôi muốn thêm thông số defaultValue cho tình trạng quá tải của TryParse cho trường hợp Tôi muốn một mặc định nếu nó không thể được phân tích cú pháp hoặc là null. Điều này hữu ích nhất khi phân tích cú pháp string.Empty hoặc null.

Lưu ý: việc triển khai này sẽ hoàn nguyên về defaultValue nếu giá trị rác được chuyển vào - vì vậy bạn có thể muốn tinh chỉnh điều đó bằng cách ném ngoại lệ.

public static T TryParse<T>(string value, T defaultValue) where T: struct 
    { 
     if (string.IsNullOrWhiteSpace(value)) 
      { 
       return defaultValue; 
      } 

      T result; 
      if (Enum.TryParse<T>(value, out result)) 
      { 
       return result; 
      } 
      else 
      { 
       return defaultValue; // you may want to throw exception here 
      } 
     } 
    } 


    ConverterMode mode = EnumUtils<ConverterMode>.TryParse(stringValue, ConverterMode.DefaultMode); 
+1

Yêu phiên bản này vì tôi nhận được thông báo Enum/value trả về nếu nó không thành công và không nhất thiết phải là 0 hoặc tiêu chuẩn khác mà tôi phải thực hiện trên tất cả các enums . – RoLYroLLs

+0

Tôi không hoàn toàn chắc chắn tại sao tôi không ném một ngoại lệ mà tôi chỉ ra ở đây, nhưng tôi nghĩ rằng đó sẽ là một cách tiếp cận tốt hơn –

+0

thực sự những gì tôi đã làm sau khi 'Enum.TryParse' là để kiểm tra xem nó đã được xác định với' Enum.IsDefined() '. Nếu không, tôi cũng làm cho nó là giá trị mặc định. Và tôi sẽ không muốn ném một ngoại lệ vào đây bởi vì đó là một 'Thử thách'. Bạn không nghĩ sao? – RoLYroLLs

0

Tôi biết điều này là cũ, nhưng dựa trên một vài mẫu, tôi đã nghiên cứu cùng với giải pháp @Simon_Weaver's, đây là những gì tôi có:

public static T TryParse(String value, T defaultValue) where T : struct { 
    if (String.IsNullOrWhiteSpace(value)) { 
     return defaultValue; 
    } 

    T result; 
    if (!Enum.TryParse(value, out result)) { 
     if (Enum.IsDefined(typeof (T), result) | result.ToString().Contains(",")) { 
      // do nothing 
     } else { 
      result = defaultValue; 
     } 
    } else { 
     result = defaultValue; 
    } 

    return result; 
}
Các vấn đề liên quan