为什么不能将??运算符应用于泛型类型,但可以应用空检查?

时间:2019-08-05 11:49:27

标签: c#

如果我有一个返回T或某个默认值的通用函数,我想使用??运算符

T f<T>(T a, T b)
{
    return a ?? b;
}

这失败并显示消息

  

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

我认为这是因为T可能不能为空。但我还要假设上面的??运算符应与

相同
T f<T>(T a, T b)
{
    var a_ = a;
    return a_ != null ? a_ : b;
}

第二个代码编译没有问题。

那么,即使这些案件应该做同样的事情,为什么这些案件也会以不同的方式处理?

3 个答案:

答案 0 :(得分:5)

来自this question on dotnet/csharplang

  

原因是??如果左侧的类型是Nullable<T>,则打算解开左侧的类型。换句话说,今天我可以写:

int? x ...;
int y ...;
int z = x ?? y;
     

因此,并非“ x ?? y”转换为“ x!= null?x:y”。它可以转换为“ x!= null?x.Value:y”。

     

由于我们不知道T是值类型还是引用类型,因此我们无法有效地进行转换。但是,如果将T约束为“类”或“结构”(在后一种情况下为T?),则可以进行转换。

请参阅该主题的其余部分以进行更广泛的讨论。

有一个discussion around relaxing this

答案 1 :(得分:0)

并非每个对象都可以为空...类可以为空。因此,您必须指出所传递的是一门课。另外,也可以使用default(T)而不是null,但是如果将'int'传递给T,则它将是零而不是null

T f<T>(T a, T b)
   where T: class
{
     ....
}

答案 2 :(得分:-1)

什么是T结构或类?那就是为什么它不能返回默认类型。

T fa<T>(T a, T b)where T :class
{
return a ?? b;
}