簡體   English   中英

幫助C#generics錯誤 - “類型'T'必須是不可為空的值類型”

[英]Help with C# generics error - “The type 'T' must be a non-nullable value type”

我是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'

您需要添加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>無效。

Nullable<T>類型對它有約束,要求T為值類型(C#中的struct )。 這就是編譯器告訴你Nullable<T>而不是你的函數或該函數的調用站點的原因 - 它是Nullable類,它是錯誤的根本原因,所以如果編譯器指向的話,這實際上更有幫助對你的功能說“這是不對的,修好它!” (想象一下,如果CoalesceMax使用了幾個泛型,並且只違反了其中一個,那么知道哪個泛型的約束被破壞比知道CoalesceMax中的一個或多個約束被破壞更有用。

解決方案是通過引入相同的約束來使您的T和它們的T兼容。 這是通過添加struct約束來完成的, struct約束必須在所有接口/新約束之前:

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

您的通用方法使用Nullable<T>

但是,你沒有約束T的類型,所以它最終可能是Nullable<Form> ,這顯然是無效的。

您需要將約束更改為where T : struct, IComparable以確保T只能是值類型。

不完全是OP的答案,但由於這是谷歌首次出現相同的錯誤消息,我不得不在我的類定義上添加約束,而不是我的方法,例如

public class MyClass<T> where T : struct
{
    public void MyMethod(T? value)
    {
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM