什么是 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.

时收到警告