我是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&lt; T&gt;'中将其用作参数'T'
答案 0 :(得分:166)
您需要添加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>
无效。
答案 1 :(得分:15)
Nullable<T>
类型对其有约束,要求T
为值类型(C#中为struct
)。这就是编译器告诉你有关Nullable<T>
而不是你的函数或该函数的调用站点的原因 - 它是导致错误的根本原因的Nullable
类,所以这实际上更有帮助如果编译器只是指向你的函数,并说“这不对,那就解决吧!” (想象一下,如果CoalesceMax
使用了几个泛型,并且只违反了其中一个,那么知道哪个泛型的约束被破坏比知道CoalesceMax
中的一个或多个约束被破坏更有用)。
解决方案是通过引入相同的约束来使您的T
及其T
兼容。这是通过添加struct
约束来完成的,该约束必须在所有接口/新约束之前:
public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{
...
}
答案 2 :(得分:5)
您的通用方法使用Nullable<T>
。
但是,您并未约束T
的类型,因此最终可能会Nullable<Form>
,这显然无效。
您需要将约束更改为where T : struct, IComparable
,以确保T
只能是值类型。
答案 3 :(得分:1)
不完全是OP的答案,但由于这是谷歌首次出现相同的错误消息,我不得不在我的类定义上添加约束,而不是我的方法,例如
public class MyClass<T> where T : struct
{
public void MyMethod(T? value)
{
}
}