如何在同一方法中处理 notnull 类和值类型?

How to handle notnull classes and valuetypes in the same method?

提问人:Tester Bill 提问时间:7/17/2022 最后编辑:Tester Bill 更新时间:7/20/2022 访问量:156

问:

请注意,整个问题假定一个可为 null 的上下文,这是 NET 6 中的默认值。

我想编写一个方法,该方法采用不可为空的类型(即结构或类)并输出该结构或类的可为空版本。像这样的东西(显然它不会只返回默认值,但不需要复杂化):Read

public static T? Read<T>()
{
    return default; //should return null
}

此示例方法应返回 null,实际上它对类、可为 null 的类和可为 null 的值类型(但不对 valuetypes)返回:

Console.WriteLine(null == Read<string>()); //true
Console.WriteLine(null == Read<string?>()); //true
Console.WriteLine(null == Read<int>()); //false
Console.WriteLine(null == Read<int?>()); //true

我想要一个为所有这些情况返回 true 的方法。我已经尝试了对 T 的一大堆约束。我觉得约束应该起作用,但事实并非如此。notnull

我可以只使用两种方法,一种限制为(即值类型),另一种限制为(即不可为空的引用类型)。以下作品:structclass

public static T? ReadValue<T>()  where T: struct
{
    return null; //does return null
}

public static T? ReadRef<T>()  where T: class
{
    return null; //does return null
}

但是,正如你所看到的,这两种方法将是相同的,没有约束和不同的名称(这是必需的,因为它们具有相同的签名)。因此,我必须为此制定两种不同的方法,这似乎很愚蠢。

对于上下文:我知道这种情况的卡顿部分是由于可为 null 的值类型在后台由 Nullable<T> 表示,而可为 null 的类仅由编译器跟踪。我只是想知道是否有办法避免这种情况。

c# .net-core null nullable-reference-types

评论

2赞 Dai 7/17/2022
“我只是想知道是否有办法避免这种情况。- 没有,真的。
4赞 madreflection 7/17/2022
我对扩展方法所做的是将它们放在不同的类中,这样签名就不会发生冲突,编译器可以选择正确的签名。由于这些不是扩展方法,因此如果您愿意在它们前面加上不同的类名,则会得到相同的效果。但这看起来与以不同的方式命名它们具有相同的缺点。
0赞 Tester Bill 7/17/2022
@madreflection这是一个非常聪明的主意,我可能会尝试一下。

答:

0赞 Guru Stron 7/17/2022 #1

AFAIK 这是不可能的,原因如下:

  1. 对于没有显式提供参数的调用,重载解决方案(对于具有显式提供的泛型类型参数的调用,您可以使用类似于此问题答案中指定的方法 - 请自行查看) - 请参阅 Jon Skeet 的精彩博客文章。

  2. 当泛型类型参数不受约束时,编译器对值和引用类型以及值类型将分别处理(请参阅答案)。TclassstructT?T?T