15

null 許容列挙型の拡張メソッドを作成しようとしています。
この例のように:

// ItemType is an enum
ItemType? item;
...

item.GetDescription();

だから私は、私が理解していない何らかの理由でコンパイルされないこのメソッドを書きました:

public static string GetDescription(this Enum? theEnum)
{
    if (theEnum == null)
        return string.Empty;

    return GetDescriptionAttribute(theEnum);
}

で次のエラーが発生しEnum?ます。

system.nullable の基になる可能性があるのは、null 非許容値型のみです。

なんで?列挙型に値を指定することはできませんnull!

アップデート:

多くの列挙型がある場合はItemType、それらの 1 つの例にすぎません。

4

4 に答える 4

20

System.Enumは であるclassため、 をドロップするだけ?で機能します。

(「これでうまくいくはずだ」とは、null 値の を渡すと、メソッドでItemType?が取得されることを意味しますnull Enum。)

public static string GetDescription(this Enum theEnum)
{
    if (theEnum == null)
        return string.Empty;
    return GetDescriptionAttribute(theEnum);
}
enum Test { blah }

Test? q = null;
q.GetDescription(); // => theEnum parameter is null
q = Test.blah;
q.GetDescription(); // => theEnum parameter is Test.blah
于 2012-10-18T14:31:09.533 に答える
4

拡張メソッドをジェネリックにするだけです。

public static string GetDescription<T>(this T? theEnum) where T : struct
{ 
    if (!typeof(T).IsEnum)
        throw new Exception("Must be an enum.");

    if (theEnum == null) 
        return string.Empty; 
 
    return GetDescriptionAttribute(theEnum); 
}

残念ながら、一般的な制約では使用できないSystem.Enumため、拡張メソッドはすべての null 許容値に対して表示されます (したがって、追加のチェックが必要です)。

編集: C# 7.3 では、次のように、ジェネリック引数を列挙型に制限できる新しいジェネリック制約が導入されました。

public static string GetDescription<T>(this T? theEnum) where T : Enum
{ 
    if (theEnum == null) 
        return string.Empty; 
 
    return GetDescriptionAttribute(theEnum); 
}

それを指摘してくれてありがとう@JeppeStigNielsen。

于 2012-10-18T14:36:39.623 に答える
3

メソッドシグネチャでは実際の列挙型を使用する必要があります。

public static string GetDescription(this ItemType? theEnum)

System.ValueType値型(それらから派生した型のみ)として扱われSystem.Enumないため、null許容型になります(null許容型として指定しないでください)。それを試してみてください:

// No errors!
ValueType v = null;
Enum e = null;

この署名を試すこともできます:

public static string GetDescription<T>(this T? theEnum) where T: struct

これはまたstructsを可能にします、それはあなたが望むものではないかもしれません。ただし、コンパイル後に型制約を追加するライブラリを覚えていると思いますenum(C#では許可されていません)。ただそれを見つける必要があります...

編集:それを見つけた:

http://code.google.com/p/unconstrained-melody/

于 2012-10-18T14:28:39.063 に答える
0

列挙型に値を追加してnullと呼ぶ方が良いかもしれません:)

于 2012-10-18T14:28:18.563 に答える