2010-07-01 15 views
25

Phương pháp tĩnh chung sau đây cần có một số chuỗi và trả lại enum.Làm thế nào tôi có thể kiểm tra nếu một enum được xác định hay không trong khi bỏ qua trường hợp?

Thật độc đáo bỏ qua trường hợp vì tôi đặt thông số ignoreCase thành true.

Tuy nhiên, tôi cũng muốn kiểm tra nếu enum tồn tại, nhưng phương pháp enum.IsDefined để làm điều này dường như không có một tham sốIgnoreCase.

Làm cách nào để kiểm tra xem enum có được xác định hay không và trong cùng một trường hợp bỏ qua?

using System; 

namespace TestEnum2934234 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      LessonStatus lessonStatus = StringHelpers.ConvertStringToEnum<LessonStatus>("prepared"); 
      ReportStatus reportStatus = StringHelpers.ConvertStringToEnum<ReportStatus>("finished"); 

      Console.WriteLine(lessonStatus.ToString()); 
      Console.WriteLine(reportStatus.ToString()); 
      Console.ReadLine(); 
     } 
    } 

    public static class StringHelpers 
    { 
     public static T ConvertStringToEnum<T>(string text) 
     { 
      if (Enum.IsDefined(typeof(T), text)) //does not have ignoreCase parameter 
       return (T)Enum.Parse(typeof(T), text, true); 
      else 
       return default(T); 
     } 
    } 

    public enum LessonStatus 
    { 
     Defined, 
     Prepared, 
     Practiced, 
     Recorded 
    } 

    public enum ReportStatus 
    { 
     Draft, 
     Revising, 
     Finished 
    } 
} 
+3

Bạn có thể muốn xem xét giá trị mặc định là Không cho thư mục của bạn. Bên cạnh đó là thực hành tốt, như nó đứng ngay bây giờ, nếu bạn vượt qua một chuỗi "Foo" cho một trong các enums của bạn, bạn sẽ có được những gì dường như là giá trị hợp lệ từ ConvertStringToEnum. – Marc

Trả lời

30
public enum MyEnum 
{ 
    Bar, 
    Foo 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var containsFoo = Enum.GetNames(typeof(MyEnum)).Any(x => x.ToLower() == "foo"); 
     Console.WriteLine(containsFoo); 
    } 
} 
27

Cùng với @ câu trả lời Darin, trong .NET 4.0, kiểu Enum bây giờ có một phương pháp TryParse:

MyEnum result; 
Enum.TryParse("bar", true, out result); 

Điều quan trọng cần nhớ là có một sự khác biệt cơ bản trong hành vi của Parse vs TryParse. Parse phương pháp sẽ ném ngoại lệ. TryParse phương pháp sẽ không. Điều này khá quan trọng để biết nếu bạn có khả năng phân tích nhiều mục.

+2

Điều này có thể trả về kết quả không mong muốn đối với các giá trị số đã xâu chuỗi. tức là 'Enum.TryParse (" 01 ", true, out result)' sẽ trả về 'true' nếu có một enum với giá trị' 1'. Mặt khác, câu trả lời của Darin sẽ chỉ phù hợp với tên enum. –

5

Sử dụng Enum.TryParse thay vì:

T val; 

if(Enum.TryParse(text, true, out val)) 
    return val; 
else 
    return default(T); 
0
public static T ConvertStringToEnum<T>(string text) 
{ 
    T returnVal; 
    try 
    { 
     returnVal = (T) Enum.Parse(typeof(T), text, true); 
    } 
    catch(ArgumentException) 
    { 
     returnVal = default(T); 
    } 
    return returnVal; 
} 
1
enum DaysCollection 
    { 
    sunday, 
    Monday, 
    Tuesday, 
    Wednesday, 
    Thursday, 
    Friday, 
    Saturday 
    } 

    public bool isDefined(string[] arr,object obj) 
    { 
     bool result=false; 
     foreach (string enu in arr) 
     { 
       result = string.Compare(enu, obj.ToString(), true) == 0; 
       if (result) 
        break; 

     } 
     return result; 


    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     object obj = "wednesday"; 
     string[] arr = Enum.GetNames(typeof(DaysCollection)).ToArray(); 

     isDefined(arr,obj); 
    } 
6

Tôi đang sử dụng Compact Framework 3.5, và:

Enum.TryParse 

... không tồn tại. Nó có:

Enum.IsDefined 

..nhưng mà không hỗ trợ các tham số IgnoreCase. Tôi muốn tốt nhất của cả hai thế giới, vì vậy đến với điều này (như là một phương pháp helper) ...

public bool TryParse<TEnum>(string value, bool ignoreCase, ref TEnum result) where TEnum : struct 
{ 
    bool parsed; 
    try 
    { 
     result = (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); 
     parsed = true; 
    } 
    catch { } 
    return parsed; 
} 

HTH

0

Làm cho văn bản cùng một trường hợp như enum chuỗi:

enum FileExts 
{ 
    jpg, 
    pdf 
} 

if (Enum.IsDefined(typeof(T), text.tolower())) //does not have ignoreCase parameter 
    return (T)Enum.Parse(typeof(T), text, true); 
else 
    return default(T); 
3

Bạn có thể thoát ra chỉ đơn giản bằng cách sử dụng Enum.TryParse, như những người khác đã nói. Tuy nhiên, nếu bạn muốn chuyển đổi mạnh mẽ hơn/chung cho phép bạn chuyển đổi nhiều hơn chỉ là chuỗi, thì bạn cũng cần sử dụng Enum.IsDefined, thật không may, như bạn thấy, là không phải là không phân biệt chữ hoa chữ thường.

Enum.TryParse (có thể) không phân biệt chữ hoa chữ thường. Nhưng thật không may, nó cho phép int-of-range ints để có được thông qua!

Vì vậy, giải pháp là sử dụng chúng cùng nhau (và thứ tự là quan trọng).

Tôi đã viết một phương pháp tiện ích mở rộng thực hiện điều đó. Nó cho phép chuyển đổi từ chuỗi, int/int ?, và bất kỳ Enum/Enum nào khác? loại như vậy:

string value1 = "Value1"; 
Enum2 enum2 = value1.ParseToEnum<Enum2>(); 
Debug.Assert(enum2.ToString() == value1); 

Enum1 enum1 = Enum1.Value1; 
enum2 = enum1.ParseToEnum<Enum2>(); 
Debug.Assert(enum2.ToString() == enum1.ToString()); 

int value2 = 1; 
enum2 = value2.ParseToEnum<Enum2>(); 
Debug.Assert(enum2.GetHashCode() == value2); 

Đây là trung tâm của phương pháp. Đây là phần chuyển đổi trả lời câu hỏi của bạn. Biến số value thuộc loại object vì "quá tải" tôi có các kiểu khác nhau làm đầu vào chính (xem ở trên), nhưng bạn có thể làm điều này với một biến kiểu string. chỉ với value).

if (value != null) 
{ 
    TEnum result; 
    if (Enum.TryParse(value.ToString(), true, out result)) 
    { 
     // since an out-of-range int can be cast to TEnum, double-check that result is valid 
     if (Enum.IsDefined(typeof(TEnum), result.ToString())) 
     { 
      return result; 
     } 
    } 
} 

Có nhiều hơn nữa với phương pháp tiện ích mở rộng của tôi ... nó cho phép bạn chỉ định mặc định, xử lý int-of-range ints tốt, và hoàn toàn không phân biệt chữ hoa chữ thường. Tôi có thể đăng thêm nếu có ai quan tâm.

+1

Chìa khóa cho tôi là ý tưởng sử dụng kết quả của đầu ra của TryParse. ToString; cảm ơn bạn. Những người khác đề nghị chỉ TryParse bỏ lỡ ints phạm vi mà có thể cho kết quả dương tính giả. – Syntax

0

Tôi có mối quan tâm tương tự và đã sử dụng kết hợp cả hai số .Enum.TryPase (với cờ không phân biệt dạng chữ được đặt là true) và Enum.IsDefined. Hãy xem xét những điều sau đây là một việc đơn giản hóa đến lớp helper của bạn:

public static class StringHelpers 
{ 
    public static T ConvertStringToEnum<T>(string text) 
    { 
     T result; 
     return Enum.TryParse(text, true, out result) 
      && Enum.IsDefined(result.ToString()) 
       ? result 
       : default(T); 
    } 
} 

Và trong khi chúng tôi đang ở đó, kể từ khi lớp helper là tĩnh và phương pháp là tĩnh - chúng ta có thể thực hiện phương pháp này một phần mở rộng trên string.

public static class StringExtensions 
{ 
    public static TEnum ToEnum<TEnum>(this string text) 
     where TEnum : struct, IComparable, IFormattable, IConvertible 
    { 
     TEnum result = default(TEnum); 
     return !string.IsNullOrWhiteSpace(text) 
      && Enum.TryParse(text, true, out result) 
      && Enum.IsDefined(typeof(TEnum), result.ToString()) 
       ? result 
       : default(TEnum); 
    } 
} 

Ở đây, tôi đã tạo một .NET Fiddle minh họa rõ ràng điều này.

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