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
的可空性吗?返回的Foo<T>
将与T
的可空性相同参数Foo<T>
?
最佳答案
对于 Foo<string?> Bar(Foo<string?> foo)
方法,接受的 foo 的类型参数与返回的 foo 的类型参数无关。目前,没有办法注释它们的可空性的预期关系。
类型参数T
在通用 Foo<T> Bar<T>(Foo<T> foo)
然而,方法将允许我们共享可空性,并且我们可以添加一个泛型类型约束,如 where T : MyType?
为了使用特定于类型的功能。
不幸的是,我们不能写where T : string?
,因为 C# 不允许将密封类用作类型约束。这是合理的,因为它以前没有意义——如果我们只能使用一种类型,为什么我们首先要将方法设计为通用的?好吧,随着 C# 8 和可空引用类型的出现,我认为我们现在可能有一个正当的理由。也许团队可以像取消枚举一样取消此限制。
回答我自己的问题:
- 没有属性来注释这个用例。
- 泛型可以与类型约束一起使用,但只能与非密封类型一起使用。
附带说明:尽管 C# 不允许我们使用密封类型作为类型约束,但 IL 允许。因此,如果编织是一个选项,我们实际上可以向泛型类型参数添加密封类型约束。类似 ExtraConstraints 的解决方案可以扩展以提供此功能。
关于c# - 匹配参数的可空性和返回类型的泛型类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58300652/