38

ユーザー文字列から取得する汎用関数を作成し、次のように列挙値に解析しようとしています:

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 を宣言する必要があることを意味しますか? どうすればこれを修正できますか? ありがとう。

4

6 に答える 6

61

TryParseメソッドには次のシグネチャがあります。

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

これには、構造体TEnumである必要があり、解析される列挙の型を決定するために使用されるジェネリック型パラメーターがあります。明示的に提供しない場合(行ったように)、引数として提供するもののタイプを受け取ります。これは、あなたの場合はタイプです(列挙自体のタイプではありません)。resultEnum

Enum( から継承しているにもかかわらず)クラスであるため、 structであるValueTypeという要件を満たしていないことに注意してください。TEnum

これを解決するには、パラメーターを削除し、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>();
于 2012-05-21T13:07:48.137 に答える
7

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

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>();
于 2012-05-21T13:08:47.353 に答える
5

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;
}

where T:struct の欠如は、信頼を開発者の手に委ねますが、未知の一般的な列挙型でコンパイルすることができます。

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

お役に立てれば。

于 2012-07-17T11:46:55.407 に答える
1

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

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

于 2012-05-21T13:07:24.687 に答える
0

文字列拡張メソッド

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

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

return Enum.Parse(typeof(TEnum), value, true);}
于 2019-05-22T07:18:45.713 に答える