web-dev-qa-db-ja.com

C#のジェネリックメソッドからNULLを返すにはどうすればよいですか?

私はこの(ダミー)コードを使った一般的な方法を持っています(はい、IListは述語を持っていますが、私のコードはIListではなく他のコレクションを使っています、とにかくこれは質問には無関係です)

static T FindThing<T>(IList collection, int id) where T : IThing, new()
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return thing;
    }
    return null;  // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead.
}

これによりビルドエラーが発生します

「nullは値型である可能性があるため、型パラメータ 'T'に変換できません。代わりに 'default(T)'の使用を検討してください。」

このエラーを回避できますか?

495
edosoft

2つの選択肢

  • default(T)を返します。これは、Tが参照型(またはNULL値型)の場合はnullintの場合は0charの場合は'\0'などを返します( デフォルト値テーブル(C#Reference)
  • where T : class制約でTを参照型になるように制限してから、通常どおりnullを返します。
865
Jon Skeet
return default(T);
77

あなただけのあなたの制約を調整することができます:

where T : class

それからnullを返すことは許されます。

29
TheSoftwareJedi

ジェネリック型の最初の制約としてクラス制約を追加します。

static T FindThing<T>(IList collection, int id) where T : class, IThing, new()
11
Min

あなたの他の選択肢はあなたの宣言の最後にこれを追加することです。

    where T : class
    where T: IList

そうすれば、nullを返すことができます。

6
BFree
  1. あなたがオブジェクトを持っているなら、それから型キャストする必要があります

    return (T)(object)(employee);
    
  2. nullを返す必要がある場合.

    return default(T);
    
6
user725388

あなたが使用できる2つのオプションは以下の通りです

return default(T);

または

where T : class, IThing
 return null;
5
Jaydeep Shil

theSoftwareJediのソリューションは、

また、いくつかの値型とnull許容型を使用してアーカイブすることもできます。

static T? FindThing<T>(IList collection, int id) where T : struct, IThing
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return thing;
    }
    return null;
}
3
devi

エラーの推奨事項...と、ユーザーdefault(T)またはnew Tのいずれかを実行してください。

あなたがそのルートに行くならそれが有効な一致であったことを確認するためにあなたのコードの中に比較を追加しなければならないでしょう。

そうでなければ、 "match found"の出力パラメータを検討する必要があります。

1
Mitchel Sellers

以下はNullable Enumの戻り値の実用的な例です。

public static TEnum? ParseOptional<TEnum>(this string value) where TEnum : struct
{
    return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value);
}
1
Luke

上記の2つの答えに代わるものです。戻り値の型をobjectに変更すると、nullを返すことができ、同時にnull以外の戻り値をキャストすることができます。

static object FindThing<T>(IList collection, int id)
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return (T) thing;
    }
    return null;  // allowed now
}
0
Jeson Martajaya