首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET 6中的可空性与泛型

问.NET 6中的可空性与泛型
EN

Stack Overflow用户
提问于 2022-07-08 12:42:17
回答 1查看 248关注 0票数 7

假设我们有一些带有两个参数的泛型方法:

代码语言:javascript
复制
private void TestConstraints<TKey>(TKey key, TKey? nullableKey)
    where TKey : notnull { }

从.NET6的角度来看,这是非常好的,在这里添加了不可空的引用类型。但是使用尝试是失败的,原因是CS8714类型不能用作参数:

代码语言:javascript
复制
private void TestMethod()
{
    var id = 5;
    int? nullableId = null;
    TestConstraints(id, nullableId);
}

警告CS8714类型为'int?‘不能用作泛型类型或方法TestClass.TestConstraints(TKey,TKey?)中的类型参数“TKey”。类型参数'int?‘的空性不匹配“notnull”约束。

显式地将类型指定为int无助。

有人能澄清我是否可以以这种方式操作(将输入参数定义为TKey?),在文档中说明它的位置?

编译器版本:

Microsoft (R)构建引擎版本17.2.0+41abc5629

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-08 13:14:16

对于不受约束(既不对struct也不对class)的泛型类型参数,对于值类型和引用类型,T - T?的处理方式不同。来自文档

  • 如果T的类型参数是引用类型,则T?引用相应的可空引用类型。例如,如果T是string,那么T?就是string?。
  • 如果T T? 的类型参数是值类型,则 T?引用相同的值类型 T**.例如,如果** T 是 int**.**,那么** T? 也是int**.**
  • 如果T的类型参数是可空引用类型,则T?引用相同的可空引用类型。例如,如果T是string?,那么T?也是string?。
  • 如果T 的类型参数是可空值类型,则 T? 引用相同的可空值类型。例如,如果T int?**,是 int?**.**,那么** T? 也是int?**.**

这部分是由于可空引用和可空值类型的处理方式不同,导致可空值类型实际上是单独的类型- Nullable。

对于TestConstraints,让我们假设T是int,然后根据规则,签名变成TestConstraints<int>(int key, int nullableKey),显然由于类型不匹配而不会为TestConstraints<int>(id, nullableId)调用编译(TestConstraints<int>(id, nullableId.Value)将编译,但在运行时抛出)。

对于int? (Nullable<int>),签名变成TestConstraints<int?>(int? key, int? nullableKey),它将编译(由于隐式转换T -> Nullable<T>),但显然会导致泛型约束失败。

解决方法可以是引入两个重载,一个用于struct,一个用于class,并让编译器弄清楚

代码语言:javascript
复制
private void TestConstraints<TKey>(TKey key, TKey? nullableKey)
        where TKey : struct
    { }
    
private void TestConstraints<TKey>(TKey key, TKey? nullableKey)
        where TKey : class
    { }
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72911604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档