[英]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.