我有以下通用方法,但是 VS 给了我一个编译错误。(运算符 '??' 不能应用于类型为 'T' 和 'T' 的操作数)
public static T Method<T>(T model) where T : new()
{
var m = model ?? new T();
}
有人知道为什么吗?
编辑:在我的情况下,可能是因为 T 可以是结构,而结构是不可为空的类型?
我有以下通用方法,但是 VS 给了我一个编译错误。(运算符 '??' 不能应用于类型为 'T' 和 'T' 的操作数)
public static T Method<T>(T model) where T : new()
{
var m = model ?? new T();
}
有人知道为什么吗?
编辑:在我的情况下,可能是因为 T 可以是结构,而结构是不可为空的类型?
??
是空合并运算符。它不能应用于不可为空的类型。由于T
可以是任何东西,它可以是一个int
或其他原始的、不可为空的类型。
如果您添加条件where T : class
(必须在之前指定new()
),它会强制T
成为一个可以为空的类实例。
您应该添加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)检查可以为空的类型,所以我们必须添加class
约束排除值类型。
编辑:Alvin Wong 的回答也涵盖了可空类型的情况;哪些实际上是结构,但可以是 ?? 的操作数 操作员。请注意,对于可空类型,如果没有 Alvin 的重载版本,Method
它将返回。null
许多人已经指出,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);
}
您需要指定您的T
类型是一个对泛型类型有约束的类:
public static T Method<T>(T model) where T : class, new()
{
return model ?? new T();
}
由于 T 可以是任何类型,因此不能保证 T 会有一个静态的 ?? 运算符或类型 T 可以为空。
这 ??运算符称为 null-coalescing 运算符,用于为可空值类型或引用类型定义默认值。
由于某种原因,该??
运算符不能用于不可为空的类型,即使它应该等同于model == null ? new T() : model
,并且您可以与不可为空的类型进行空比较。
通过使用三元运算符或 if 语句,您可以在没有任何额外约束的情况下准确地获得您正在寻找的内容:
public static T Method<T>(T model) where T : new()
{
var m = model == null ? new T() : model;
}
model ?? new T()
意味着model == null ? new T() : model
。不保证模型不可为空且==
不可申请null
且不可为空的对象。将约束更改为where T : class, new()
应该有效。
将 T 标记为“类”,您就可以开始了。