Mat*_*son 8 c# nullable-reference-types
.Net Core定义object.ToString()为public virtual string? ToString();
这意味着如下代码会引发CS8602“取消引用可能为空引用”警告:
object t = "test";
var s = t.ToString();
Console.WriteLine(s.Length); // Warning CS8602
Run Code Online (Sandbox Code Playgroud)
这可以通过编写s!.Length或轻松解决t.ToString()!;,但我的问题是:
null在什么情况下从 的实现返回是正确的object.ToString()?
答案似乎是:“你永远不应该从 object.ToString() 返回 null”,这很公平 - 但这确实提出了另一个问题,即“在这种情况下,微软为什么将其声明为public virtual string? ToString();”?
在旁边:
下面的一些评论表明,由于实现可能会错误地返回 null,因此必须将返回值声明为string?.
如果这是真的,那么为什么相同的逻辑不适用于没有ICloneable.Clone()声明为返回的?object?
这个逻辑肯定适用于返回引用类型的每个接口方法吗?ICustomFormatter.Format()理论上,此类方法的任何实现(例如, )都可以返回null- 因此返回值应该可以为 null。但他们不是。
阅读 DavidG 提供的链接后,我相信该主题中的讨论回答了我满意的问题:
我不明白为什么有人想要anything.ToString()回来null,但谁知道呢?
然后,我认为出于兼容性原因object.ToString()被定义为返回 a string?:这自 .NET v1 以来就存在,并且始终定义为返回 astring并且 astring作为引用类型可以为 null。“现代”声明只是指出:返回的字符串有可能为空。
并且请记住,这个string?东西是最近才出现的,并且只是元数据:即使它是键入的string(就像在旧版本中一样),实现仍然可以设法返回 null。
换句话说,全新的 API 可以(并且应该)根据需要使用Nullable注释,但现有库的重新键入必须尊重库所做的事情。
我说重新输入是因为它并不是真正的输入,只是指示预期行为的注释。这有点类似于 Typescript “注释”Javascript 代码的方式:底层类型系统仍然是旧的类型系统。