在什么情况下`object.ToString()`应该返回null?

时间:2021-02-24 12:46:39

标签: c# nullable-reference-types

.Net 核心 defines object.ToString() as public virtual string? ToString();

这意味着像下面这样的代码会引发CS8602“可能为空引用的取消引用”警告:

object t = "test";
var s = t.ToString();
Console.WriteLine(s.Length); // Warning CS8602

这很容易通过写 s!.Lengtht.ToString()!; 解决,但我的问题是:

在什么情况下从 null 的实现中返回 object.ToString() 是正确的?


答案似乎是:“你永远不应该从 object.ToString() 返回 null”,这很公平——但这确实引发了另一个问题,即“在这种情况下,为什么微软将其声明为 { {1}}”?


旁白:

下面的一些评论表明,由于实现可能错误地返回 null,因此必须将返回值声明为 public virtual string? ToString();

如果这是真的,那么为什么同样的逻辑不适用于 ICloneable.Clone(),它没有声明为返回 string?

这个逻辑肯定适用于每个返回引用类型的接口方法吗?这种方法的任何实现(例如,object?)理论上都可以返回ICustomFormatter.Format() - 因此返回值应该可以为空。但他们不是。


阅读 DavidG 提供的链接后,我相信该主题中的讨论让我满意地回答了这个问题:

https://github.com/dotnet/coreclr/pull/23466

1 个答案:

答案 0 :(得分:1)

我想不出为什么人们会希望 anything.ToString() 返回 null,但谁知道呢?

然后,我认为 object.ToString() 被定义为出于兼容性原因返回 string?:这自 .NET v1 以来就存在,并且始终被定义为返回 string 和 {{1 }} 作为引用类型可以为空。 '现代' 声明简单地说:返回的字符串有可能为空。

请记住,这个 string 是最近才出现的,而且只是元数据:即使输入了 string?(就像在旧版本中一样),实现仍然可以设法返回 null。

换句话说,全新的 API 可以(并且应该)根据需要使用 Nullable 注释,但是对现有库的重新输入必须尊重什么图书馆做到了。

我说重新输入是因为它并不是真正的输入,只是指示预期行为的注释。这有点类似于 Typescript“注释”Javascript 代码的方式:底层类型系统仍然是旧的。

相关问题