C#のジェネリックエラーのヘルプ-「タイプ 'T'はnullにできない値のタイプでなければなりません」


100

C#は初めてですが、次のコードが機能しない理由がわかりません。

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : IComparable
{
    if (a.HasValue && b.HasValue)
        return a.Value.CompareTo(b.Value) < 0 ? b : a;
    else if (a.HasValue)
        return a;
    else
        return b;
}

// Sample usage:
public DateTime? CalculateDate(DataRow row)
{
    DateTime? result = null;
    if (!(row["EXPIRATION_DATE"] is DBNull))
        result = DateTime.Parse((string)row["EXPIRATION_DATE"]);
    if (!(row["SHIPPING_DATE"] is DBNull))
        result = CoalesceMax(
            result
            DateTime.Parse((string)row["SHIPPING_DATE"]).AddYears(1));
    // etc.
    return result;
}

コンパイル中に次のエラーが発生します。

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

1
コンパイラエラーは関数定義の行を提供します。なぜならエラーがそこにあるからです。
10

回答:


180

T : struct制約を追加する必要があります:

public static Nullable<T> CoalesceMax<T>
    (Nullable<T> a, Nullable<T> b) where T : struct, IComparable

そうでない場合、C#は何をNullable<T>意味するのかを試み、Nullable<T>それ自体が必要とする制約がまだないことを認識します。つまり、次のように呼び出すことができます。

CoalesceMax<string>(...)

これはNullable<string>有効ではないので意味がありません。


16

Nullable<T>タイプが必要とそれに制約有するT(値型であるとstructC#での)。それがコンパイラがNullable<T>あなたの関数やその関数の呼び出しサイトではなくあなたに言っている理由です-それNullableはエラーの根本的な原因であるクラスなので、コンパイラがあなたの関数を指し示して言った場合、これは実際にもっと役に立ちます「これは正しくありません。修正してください!」(CoalesceMax複数のジェネリックを使用し、そのうちの1つだけの制約に違反した場合を想像してください。1つ以上の制約CoalesceMaxが壊れていることを知るよりも、どのジェネリックの制約が壊れているかを知る方が便利です)。

解決策は、同じ制約を導入することであなたTと彼らのT互換性を作ることです。これはstruct、すべてのインターフェース/新しい制約の前にある制約を追加することによって行われます。

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{
  ...
}

6

ジェネリックメソッドはを使用していNullable<T>ます。

ただし、のタイプを制限していないため、T最終的にになる可能性がありNullable<Form>、明らかに無効です。

が値タイプのみになるwhere T : struct, IComparableようにするには、制約を変更する必要Tがあります。


2

正確にはOPへの回答ではありませんが、これは同じエラーメッセージが表示されてgoogleに最初に表示されたため、メソッドではなく、クラス定義に制約を追加する必要がありました。

public class MyClass<T> where T : struct
{
    public void MyMethod(T? value)
    {
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.