【发布时间】:2020-03-20 05:53:51
【问题描述】:
在 C# 8.0 中,我们可以拥有可为空的引用类型。 The docs 声明有 4 种类型的可空性。前三个很清楚,但我不明白“未知”的意思。文档说它与泛型一起使用,但是当我尝试在泛型中对 T 类型的无约束变量调用方法时,它只会发出警告,好像该类型可以为空。我看不出未知和可空之间的区别。为什么未知存在?它是如何表现出来的?
【问题讨论】:
标签: c# c#-8.0 nullable-reference-types
在 C# 8.0 中,我们可以拥有可为空的引用类型。 The docs 声明有 4 种类型的可空性。前三个很清楚,但我不明白“未知”的意思。文档说它与泛型一起使用,但是当我尝试在泛型中对 T 类型的无约束变量调用方法时,它只会发出警告,好像该类型可以为空。我看不出未知和可空之间的区别。为什么未知存在?它是如何表现出来的?
【问题讨论】:
标签: c# c#-8.0 nullable-reference-types
采取以下通用方法:
public static T Get<T>(T value)
{
return value;
}
如果我们称它为Get<string>(s),则返回不可为空,如果我们称其为Get<string?>(s),则返回可空。
但是,如果您使用诸如 Get<T>(x) 和 T 之类的通用参数调用它,则无法解析,例如,它是您的通用类的通用参数,如下所示...
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// is result nullable or non-nullable? It depends on T
}
}
这里编译器不知道最终是否会使用可空类型或不可空类型调用它。
我们可以使用一个新的类型约束来表示T 不能为空:
public static T Get<T>(T value) where T: notnull
{
return value;
}
但是,在 T 不受约束且仍然打开的情况下,可空性是未知的。
如果这些未知数被视为可以为空,那么您可以编写以下代码:
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// reassign result to null, cause we we could if unknown was treated as nullable
result = null;
}
}
在T 不可为空的情况下,我们应该得到一个警告。因此,对于未知的可空性类型,我们希望在取消引用时发出警告,但也希望在分配潜在的 null 时发出警告。
【讨论】: