如果强制转换为null,为什么Convert.ToString(null)返回不同的值?


116
Convert.ToString(null)

退货

null

如我所料。

Convert.ToString(null as object)

退货

""

为什么这些不同?

Answers:


143

这里有2个重载在ToString起作用

Convert.ToString(object o);
Convert.ToString(string s);

C#编译器从本质上尝试选择最特定的重载,该重载将与输入配合使用。甲null值转换为任何引用类型。在这种情况下string比更为具体object,因此将被选为获胜者。

在中,null as object您将表达式的类型固定为object。这意味着它不再与string重载兼容,并且编译器选择了object重载,因为它是剩余的唯一兼容重载。

C#语言规范的7.4.3节介绍了如何打破平局的真正毛茸茸的细节。


15
好。因此,它使用一种过载而不是另一种过载。说得通。但是,两个重载都不应该返回相同的东西吗?+1 btw。
约翰·麦金太尔

2
@JohnMacIntyre-这取决于开发团队而不是编译器。
JonH 2012年

8
@JohnMacIntyre如果您看一下Convert.ToString(string)它的实现,它只是一个标识函数,而Convert.ToString(object)实际上却经历了一条难以遵循的道路。乍一看,我同意他们应该返回相同的内容,但BCL的可转换层并不是我很了解的东西,并且有可能存在很大的差异(尽管我对此表示怀疑)
JaredPar

我是来这里寻找如何将空对象转换为空字符串的。对于其他搜索者来说(string)null,答案是,或者,如果您反对,则称之为(string)o
rayzinnz

65

接下来是JaredPar出色的重载解决方案答案-问题仍然是:“为什么Convert.ToString(string)返回null,但是Convert.ToString(object)返回string.Empty”?

答案是...因为文档这样说的:

Convert.ToString(string)返回“指定的字符串实例;不执行任何实际转换。”

Convert.ToString(object)返回“值的字符串表示形式,如果value为null,则返回String.Empty”。

编辑:关于这是否是“规范中的错误”,“ API设计非常糟糕”,“为什么这样指定”等-我将为一些为什么我看不到的理由开枪没什么大不了的。

  1. System.Convert 具有将每种基本类型转换为 自身的方法。这很奇怪-由于不需要或不可能进行任何转换,因此这些方法最终仅返回参数。Convert.ToString(string)表现相同。我认为这些是用于代码生成方案的。
  2. Convert.ToString(object)通过时有3个选择null。抛出,返回null或返回string.Empty。抛出将是不好的-双重假设是将它们用于生成的代码。返回null要求您的调用者进行null检查-再次,在生成的代码中不是一个很好的选择。返回string.Empty似乎是一个合理的选择。其余的System.Convert涉及值类型-具有默认值。
  3. 返回null是否更“正确”是有争议的,但是string.Empty绝对更有用。更改Convert.ToString(string)意味着打破“无实际转换”规则。由于System.Convert是静态实用程序类,因此每个方法在逻辑上都可以视为自己的方法。在现实世界中,很少有这种行为“令人惊讶”的情况,因此让可用性赢得(可能的)正确性。

可以公平地说这是规范中的错误吗?
约翰·麦金太尔

3
但这并不能回答为什么会这样。之所以说它的行为是这样的,是因为据证明它的行为是重言式的。
CodesInChaos

2
@JohnMacIntyre IMO可以公平地说这是非常糟糕的API设计。
CodesInChaos

7
@CodeInChaos-不是重言式,除非您假设文档是在BCL开发之后根据可观察到的行为编写的。我认为这是一个奇怪的假设。IOW,这不是“记录在案,以这样的表现”,它的“记载,它这样的表现。” -也就是说,它的“ 指定到这样的表现。”
Mark Brackett 2012年

8
它仅将问题转移到“为什么要指定其表现为这种方式”
CodesInChaos 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.