gpt4 book ai didi

c# - 带有泛型的可为空引用的注释

转载 作者:行者123 更新时间:2023-12-04 11:29:12 24 4
gpt4 key购买 nike

鉴于以下通用 Foo1功能:

struct Key<T> {}
static readonly Key<double> MyKey = new Key<double>();
T? Foo1<T>(Key<T> key)
{
return default;
}
一个天真的读者会假设:
var foo1 = Foo1(MyKey);
foo1类型为 double? ,事实证明编译器正在选择 double对于返回类型。我需要明确地添加一个约束来获得一个可以为空的返回值:
T? Foo2<T>(Key<T> key) where T : struct // really return a nullable
{
return default;
}
有人可以解释为什么可以为空引用的注释 ?我的第一次没有被接走 Foo1功能 ?

最佳答案

让我们从一些背景开始:
C# 9.0 之前 Foo1无效。即使在启用了可为空引用的 C# 8.0 中:

CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type
Foo2甚至在 C# 8.0 之前就有效,因为 T?只有在 T 时才有意义是一个结构体,在本例中 T?T 的类型不同( Nullable<T> )。到目前为止,这很简单。
从 C# 8.0 开始引入了可空引用,这引起了一些困惑。从现在开始 T?可以表示 Nullable<T>或只是 T .此版本不允许 T?没有约束,但在您指定 where T : class 时也允许.
在不使用约束的情况下,您必须使用属性来指示 T可以 null作为返回值:
// C# 8.0: Poor man's T?
[return: MaybeNull] T Foo1<T>(Key<T> key) => default;
如果 T现在是值类型吗?它显然不会将其类型更改为 Nullable<T>在返回值中。返回 double?您的类型参数也必须是 double? , 意思, MyKey也必须是 Key<double?> .
在 C# 9.0 中对 T? 的限制已经放松了,现在不需要约束了:
// C# 9.0: this is valid now
T? Foo1<T>(Key<T> key) => default;
但它现在基本上与 C# 8.0 版本的含义相同。没有 where T : struct约束 T?T 的类型相同所以它只是表明结果可以是 null ,它可以出现在编译器警告中。要返回可空值类型,您必须使用 double?作为通用参数,这也意味着您的 Key还必须定义可空类型:
static readonly Key<double?> MyKey = new Key<double?>();
如果可空键在您的情况下没有意义,那么您只能指定 where T : struct约束如 Foo2所以旧规则开始生效: T?T有不同的类型,其中 T?意味着 Nullable<T> .

更新: Foo1的主要区别和 Foo2如果你看到他们的 decompiled source 可能更明显:
[System.Runtime.CompilerServices.NullableContext(2)]
private static T Foo1<T>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Key<T> key)
{
return default(T);
}

private static Nullable<T> Foo2<T>(Key<T> key) where T : struct
{
return null;
}
注意返回类型 Foo1就是 T带有一些注释,以便编译器可以发出正确的警告。

关于c# - 带有泛型的可为空引用的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69211372/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com