接线员'??'不能应用于'T'和'T'类型的操作数

时间:2013-06-13 06:17:28

标签: c# generics compiler-errors

我有以下通用方法,但VS给我一个编译错误。 (运算符'??'不能应用于'T'和'T'类型的操作数

public static T Method<T>(T model) where T : new()
{
    var m = model ?? new T();
}

有人知道为什么吗?

编辑:可能的原因是T在我的情况下可以是结构,而结构是不可空的类型吗?

8 个答案:

答案 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 (C# Reference)

  

?? 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标记为“班级”,你很高兴。