2012-05-21 106 views
19

我試圖建立通用的功能,從用戶的字符串獲得並嘗試將其解析到枚舉valuse這樣的:如何在Enum中使用泛型Tryparse?

private Enum getEnumStringEnumType(Type i_EnumType) 
    { 
     string userInputString = string.Empty; 
     Enum resultInputType; 
     bool enumParseResult = false; 

     while (!enumParseResult) 
     {     
      userInputString = System.Console.ReadLine(); 
      enumParseResult = Enum.TryParse(userInputString, true, out resultInputType); 
     } 
    } 

,但我得到:

The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'TEnum' in the generic type or method 'System.Enum.TryParse<TEnum>(string, bool, out TEnum) . 

的錯誤意味着,我需要decalare resultInputType的特定枚舉? 我該如何解決這個問題? 謝謝。

+0

當你說「通用函數」 - 你的方法*不是*通用的。你是否需要能夠將類型指定爲「Type」值而不是將其作爲一種真正的通用方法? –

回答

37

TryParse method具有以下特徵:

TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) 
    where TEnum : struct 

它有一個一般類型參數TEnum必須是結構並且被用於確定正在分析枚舉的類型。如果你沒有明確地提供它(和你一樣),它將採用你提供的任何類型作爲參數result,在你的情況下它的類型是Enum(而不是枚舉類型本身)。

注意Enum is a class(儘管它從ValueType繼承),因此它不能滿足該TEnum結構的要求。

可以通過去除Type參數和給予方法與相同的約束爲對TryParse功能一般類型參數的通用類型參數(即struct)解決此問題。

那麼試試這個,在這裏我命名泛型類型參數TEnum

private static TEnum GetEnumStringEnumType<TEnum>() 
    where TEnum : struct 
{ 
    string userInputString = string.Empty; 
    TEnum resultInputType = default(TEnum); 
    bool enumParseResult = false; 

    while (!enumParseResult) 
    {     
     userInputString = System.Console.ReadLine(); 
     enumParseResult = Enum.TryParse(userInputString, true, out resultInputType); 
    } 
    return resultInputType; 
} 

要調用該方法,使用:

GetEnumStringEnumType<MyEnum>(); 
+0

Enum.TryParse是通用的... http://msdn.microsoft.com/en-us/library/system.enum.aspx – eyossi

+0

這是正確的。我從來沒有說過不是。它的簽名是'TryParse (字符串值,bool ignoreCase,out TEnum結果),其中TEnum:struct,new()',如果指定了'result',它將使用該變量的類型來確定'TEnum',從明確指定它。 – Virtlink

+1

我得到相同的錯誤:類型'TEnum'必須是不可爲空的值類型,以便將其用作通用類型或方法'System.Enum.TryParse中的參數'TEnum'(string,bool,out TEnum )。 – Rami

2

Enum.TryParse是一個通用的方法,這意味着它的泛型類型參數必須在編譯時已知。這反過來意味着是的,你必須聲明resultInputType作爲特定 enum類型的代碼來編譯。

如果你想就可以了,原來的代碼是有點過於樂觀:無處它說枚舉類型應與名稱等於userInputString成員進行檢查。沒有這些信息,TryParse如何工作?

4

你應該做一個通用的方法:

private T getEnumStringEnumType<T>() where T : struct, IConvertible 
    { 
     string userInputString = string.Empty; 
     T resultInputType = default(T); 
     bool enumParseResult = false; 

     while (!enumParseResult) 
     { 
      userInputString = System.Console.ReadLine(); 
      enumParseResult = Enum.TryParse<T>(userInputString, out resultInputType); 
     } 

     return resultInputType; 
    } 

用法:

public enum myEnum { val1, val2 } 

myEnum enumValue = getEnumStringEnumType<myEnum>(); 
+0

我得到相同的erroe:類型'T'必須是不可爲空的值類型,以便將其用作泛型類型或方法'System.Enum.TryParse中的參數'TEnum'(string,out TEnum); – Rami

+0

遵循更新後的代碼(我添加了T:struct,new())。並查看使用示例 – eyossi

+0

-1:由於三個原因,您的代碼無法編譯。 – Virtlink

1

很久以前在Visual Studio 2005時代,我在Enum上爲TryParse做了我自己的方法。我最近才發現了2008年的實施情況,我對它的限制性並不滿意,特別是考慮到這是一種方法;這意味着程序員正在測試輸入!

一般情況下,我更喜歡使用其信任程序員方法知道自己在做什麼:)

我的實現如下:

public static bool EnumTryParse<T>(string input, out T theEnum) 
{ 
    foreach (string en in Enum.GetNames(typeof(T))) 
    { 
     if (en.Equals(input, StringComparison.CurrentCultureIgnoreCase)) 
     { 
      theEnum = (T)Enum.Parse(typeof(T), input, true); 
      return true; 
     } 
    } 

    theEnum = default(T); 
    return false; 
} 

缺少的,其中T:結構把信任在開發者手中,但它允許您使用未知的泛型枚舉進行編譯。

作爲替代方案,如果要在轉換爲指定的枚舉時進行整數比較,則可以在Enum.GetValues上創建一個循環方法。

希望這會有所幫助。