什么是 C# 8 中的未知可空性?
What is Unknown Nullability in C# 8?
在 C# 8.0 中,我们可以拥有可为空的引用类型。 The docs 指出有 4 种类型的可空性。前三个很清楚,但我不明白 "unknown" 的要点。文档说它与泛型一起使用,但是当我尝试在泛型中的 T 类型的无约束变量上调用方法时,它只是发出警告,好像该类型可以为空。我看不出未知和可为空之间的区别。为什么未知存在?它是如何表现出来的?
采用以下通用方法:
public static T Get<T>(T value)
{
return value;
}
如果我们像 Get<string>(s)
那样称呼它,return 是不可为 null 的,如果我们这样称呼它 Get<string?>(s)
,它是可以为 null 的。
但是,如果您使用 Get<T>(x)
之类的通用参数调用它并且 T
未解析,例如它是您的通用 class 的通用参数,如下所示。 ..
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
.
时收到警告
在 C# 8.0 中,我们可以拥有可为空的引用类型。 The docs 指出有 4 种类型的可空性。前三个很清楚,但我不明白 "unknown" 的要点。文档说它与泛型一起使用,但是当我尝试在泛型中的 T 类型的无约束变量上调用方法时,它只是发出警告,好像该类型可以为空。我看不出未知和可为空之间的区别。为什么未知存在?它是如何表现出来的?
采用以下通用方法:
public static T Get<T>(T value)
{
return value;
}
如果我们像 Get<string>(s)
那样称呼它,return 是不可为 null 的,如果我们这样称呼它 Get<string?>(s)
,它是可以为 null 的。
但是,如果您使用 Get<T>(x)
之类的通用参数调用它并且 T
未解析,例如它是您的通用 class 的通用参数,如下所示。 ..
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
.