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

dan*_*iol 5 c#

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

T f<T>(T a, T b)
{
    return a ?? b;
}
Run Code Online (Sandbox Code Playgroud)

消息失败

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

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

T f<T>(T a, T b)
{
    var a_ = a;
    return a_ != null ? a_ : b;
}
Run Code Online (Sandbox Code Playgroud)

第二个代码可以毫无问题地进行编译。

那么,为什么这些案件即使应该采取同样的措施也要以不同的方式处理?

can*_*on7 5

dotnet / csharplang上的这个问题来看:

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

int? x ...;
int y ...;
int z = x ?? y;
Run Code Online (Sandbox Code Playgroud)

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

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

有关更多讨论,请参见该线程的其余部分。

关于放松这个话题,有一个讨论