1

私はこの簡単なユーティリティ関数を書きました:

public static T isNull<T>(T? v, T d)
{
    return v == null ? d : v.Value;
}

目的は、linq レコードセットの読み取りで非常に一般的な、メンバーが null であることを確認するような面倒なタスクを回避することです。問題は、このエラーがスローされていることです。

型 'T' は、ジェネリック型またはメソッド 'System.Nullable< T>' でパラメーター 'T' として使用するために、null 非許容値型である必要があります。

エラーは正当なようですが、とにかく、次のようなことができればいいのにと思います:

int? myField = record.myField;
int  myValue = isNull(myField, 0);

それ以外の:

int? myField = record.myField;
int  myValue = myField == null ? 0 : myField.Value;

C# の基本的な知識が不足しているように感じます。私の仕事を達成する方法はありますか?

4

3 に答える 3

6

ジェネリック制約をジェネリック関数で使用して、使用できる型を特定のサブセットに制限できます。これにより、メソッドまたはクラス内でこれらの型を使用する方法の可能性が開かれます。

この場合、特定のコンパイラ エラーを解決するためTに、制限を に適用することができます。struct

public static T IsNull<T>(T? v, T d) where T : struct
{
    return v == null ? d : v.Value;
}

??ただし、別の回答は、この特定の状況でnull 合体演算子を使用することを選択できることを正しく指摘しています。

于 2013-03-29T01:48:40.427 に答える
4

これは null 合体と呼ばれ、それを行う組み込みの演算子があります。

int myValue = record.myField ?? 0
于 2013-03-29T01:52:14.243 に答える
3

他の答えは良いですが、おそらく参照型と値型の両方で機能するようにメソッドを書きたいと思うでしょう。これは、2 つのオーバーロードを両方とも一般的な制約と共に使用することで実現できます。

public static T IsNull<T>(T v, T d) where T : class
{
    return v ?? d;
}

public static T IsNull<T>(T? v, T d) where T : struct
{
    return v.HasValue ? v.Value : d;
}

注:IsNull以外の値の型で呼び出すと、Nullable<T>まだコンパイルされません。例えば

string myString = ...
Console.WriteLine(IsNull(myString, "foo"))            // works

object myObject = ...
Console.WriteLine(IsNull(myMyObject, new object()))   // works

DateTime? myDateTime = ...
Console.WriteLine(IsNull(myDateTme, DateTme.Now))     // works

int? myInt1 = ...
Console.WriteLine(IsNull(myInt1, DateTme.Now))        // works

int myInt2 = ...
Console.WriteLine(IsNull(myInt2, DateTme.Now))        // <-- compiler error
于 2013-03-29T02:03:41.460 に答える