匹配参数和返回类型的泛型类型参数的可空性

时间:2019-10-09 09:07:12

标签: c# .net-core .net-core-3.0 c#-8.0 nullable-reference-types

public readonly struct Foo<T>
{
    // ...
    public T Value { get; }
}

public static Foo<string?> Bar(Foo<string?> foo)
{
    if (foo.Value is null) { /* Something */ }
    else { /* Some other thing */ }
    return foo;
}

public static void Main()
{
    var foo1 = new Foo<string>("s");
    var ret1 = Bar(foo1); // Warns because foo1's type parameter is not nullable

    var foo2 = new Foo<string?>("s");
    var ret2 = Bar(foo2); // Ok because foo2's type parameter is nullable
}
  • 我可以写Bar接受Foo<string?>Foo<string>吗?
  • 我可以为Bar注释以指定“进出什么”,所以返回的T的{​​{1}}的可空性将与参数Foo<T>的可空性相同T

1 个答案:

答案 0 :(得分:0)

对于Foo<string?> Bar(Foo<string?> foo)方法,接受的foo的type参数与返回的foo的type参数无关。目前,还没有办法注释其无效性的预期关系。

但是,在通用T方法中的

类型参数Foo<T> Bar<T>(Foo<T> foo)将允许我们共享可空性,并且可以添加诸如where T : MyType?之类的通用类型约束,以便使用特定于类型的类型功能。

不幸的是,我们无法编写where T : string?,因为C#不允许将密封类用作类型约束。这是合理的,因为以前是没有道理的-如果无论如何我们只能使用一种类型,为什么为什么要首先将方法设计为泛型呢?好吧,随着C#8和可空引用类型的出现,我认为我们现在可能有一个合理的理由。也许团队可以取消此限制,因为他们取消了枚举。

要回答我自己的问题:

  • 没有用于注释此用例的属性。
  • 泛型可以用于类型约束,但只能用于未密封的类型。

作为旁注:即使C#不允许我们将密封类型用作类型约束,IL也可以。因此,如果编织是一种选择,我们实际上可以向通用类型参数添加密封类型约束。可以扩展诸如ExtraConstraints之类的解决方案以提供此功能。

相关问题