web-dev-qa-db-ja.com

Enumで一般的なTryparseを使用する方法?

ユーザー文字列から取得するジェネリック関数を作成して、次のようにEnum valuseに解析しようとしています。

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)    .

エラーは、resultInputTypeの特定のEnumをデカールする必要があることを意味しますか?どうすれば修正できますか?ありがとう。

33
Rami

TryParse method には次のシグネチャがあります:

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

structである必要があるジェネリック型パラメーターTEnumがあり、解析される列挙型を決定するために使用されます。 (明示的に)明示的に指定しない場合、result引数として指定したもののタイプが使用されます。この場合、タイプはEnumです(そして、列挙自体のタイプ)。

EnumclassValueTypeから継承しているにもかかわらず)であり、したがってTEnumstructであるという要件を満たしていません。

これを解決するには、Typeパラメーターを削除し、struct関数のジェネリック型パラメーターと同じ制約(つまりTryParse)を持つジェネリック型パラメーターをメソッドに指定します。

だから、これを試してみてください。ここで、ジェネリック型パラメーターに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>();

ジェネリックメソッドを作成する必要があります。

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>();
5
eyossi

Visual Studio 2005時代のずっと前に、EnumのTryParseに独自のメソッドを作成しました。 2008年の実装を最近発見したばかりで、特にTRY PARSEメソッドであることを考えると、その制限に満足していません。プログラマーが入力をテストしていることを意味します!

一般的に、私はプログラマーが彼のしていることを知っていると信頼できる方法を使うことを好みます:)

私の実装は次のとおりです:

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:structが開発者の手に委ねる場所がないため、未知の一般的な列挙型でコンパイルできます。

別の方法として、指定した列挙型に変換するときに整数比較を行う場合は、Enum.GetValuesでループするメソッドを作成できます。

お役に立てれば。

3
Mark Mintoff

Enum.TryParseはジェネリックメソッドです。つまり、そのジェネリック型パラメーターはコンパイル時に認識される必要があります。これはつまり、はい、コードをコンパイルするには、resultInputTypespecific列挙型として宣言する必要があります。

考えてみると、元のコードは少し楽観的すぎます。どこにも書かれていないwhich列挙型は、userInputStringと等しい名前のメンバーをチェックする必要があります。この情報なしでTryParseはどのように機能しますか?

1
Jon

文字列拡張メソッド

public TEnum ToEnum<TEnum>(this string value, TEnum defaultValue){

if (string.IsNullOrEmpty(value))return defaultValue;

return Enum.Parse(typeof(TEnum), value, true);}
0
AHMED RABEE