我有以下通用方法,但VS给我一个编译错误。 (运算符'??'不能应用于'T'和'T'类型的操作数
public static T Method<T>(T model) where T : new()
{
var m = model ?? new T();
}
有人知道为什么吗?
编辑:可能的原因是T在我的情况下可以是结构,而结构是不可空的类型吗?
答案 0 :(得分:83)
??
是null-coalescing运算符。它不能应用于非可空类型。由于T
可以是任何内容,因此它可以是int
或其他原始的,不可为空的类型。
如果添加条件where T : class
(必须在new()
之前指定),它会强制T
成为可以为空的类实例。
答案 1 :(得分:57)
您应该添加class
约束:
public static T Method<T>(T model) where T : class, new()
{
var m = model ?? new T();
return m;
}
你也应该返回m
!
注意:正如@KristofDegrave在评论中提到的那样,我们必须添加class
约束的原因是因为T可以是值类型,例如int
和??
运算符( null-coalescing)检查可以为null的类型,因此我们必须添加class
约束来排除值类型。
编辑:Alvin Wong的答案涵盖了可空类型的案例;实际上是结构,但可以是??的操作数?运营商。请注意,如果没有Alvin的重载版本,Method
将返回null
,因为可以为空的类型。
答案 2 :(得分:32)
许多人已经指出,为泛型添加class
约束将解决问题。
如果您希望自己的方法适用于Nullable<T>
,则可以为其添加重载:
// For reference types
public static T Method<T>(T model) where T : class, new()
{
return model ?? new T();
}
// For Nullable<T>
public static T Method<T>(T? model) where T : struct
{
return model ?? new T(); // OR
return model ?? default(T);
}
答案 3 :(得分:8)
您需要指定您的T
类型是一个对泛型类型有约束的类:
public static T Method<T>(T model) where T : class, new()
{
return model ?? new T();
}
答案 4 :(得分:4)
由于T可以是任何类型,因此不能保证T会有静态?运算符或类型T可以为空。
?? operator被称为null-coalescing运算符并且习惯于 为可空值类型或引用定义默认值 类型强>
答案 5 :(得分:4)
由于某种原因,??
运算符不能用于非可空类型,即使它应该等同于model == null ? new T() : model
,并且是允许的与非可空类型的空比较。
通过使用三元运算符或if语句,您可以在不受任何其他限制的情况下获得您正在寻找的内容:
public static T Method<T>(T model) where T : new()
{
var m = model == null ? new T() : model;
}
答案 6 :(得分:0)
model ?? new T()
表示model == null ? new T() : model
。不保证模型不可为空,==
不能应用于null
和不可为空的对象。将约束更改为where T : class, new()
应该有效。
答案 7 :(得分:0)
将T标记为“班级”,你很高兴。