为什么我不能像使用空引号一样将string.Empty用作可选参数?

6

我正在优化我的代码,注意到有些地方的可选参数默认值是空字符串。我将其更改为来自类的默认空字符串值,但是你猜怎么着!显然,空引号和string.Empty之间存在差异。真是让人惊奇!(故意打错字)

private void Khaboom(String parameter = "") { ... }

private void Bazinga(String parameter = String.Empty) { ... }

有人能解释一下为什么 Khaboom 能运行而 Bazinga 却不能吗?!

错误信息如下:

"parameter" 的默认参数值必须是编译时常量。

但是,它就是编译时常量啊!


1
@MichaelPerrenoud 重复了什么? - Konrad Viltersten
我将其标记为重复项,但随后重新打开了它。 - Mike Perrenoud
3个回答

13

Empty的定义如下:

public static readonly string Empty

它不是常量,而是只读字段。


6
对于那些想知道为什么它不是一个常量的人,实际上可能有一个非常好的原因。请参考这篇文章:http://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/。 - Doctor Blue
@Scott... 我确实想知道... 谢谢。 - spender
@Scott,你的链接并没有给出为什么string.Empty没有被选为一个const字段的好理由。原因更加难以理解。在Stack Overflow上有一些关于这个话题的讨论。 - Jeppe Stig Nielsen
@JeppeStigNielsen:在哪里? - spender
https://dev59.com/o3RB5IYBdhLWcg3wyqOo - Jeroen Vannevel
请注意,旧的(有问题的?)决定不将string.Empty作为文字常量,可能已在.NET 4.5版本中得到补偿。实际上,自从4.5以来,当您从string.Empty读取时,例如由C#编译器创建的IL代码,运行时会"欺骗"并替换为空字符串,而不是读取静态字段所持有的实际字符串引用。这种优化似乎使string.Empty在代码运行时更像常量。但在编译时它仍然不是真正的常量,因此上面的答案是正确的。 - Jeppe Stig Nielsen

4
默认值必须是以下类型之一的表达式:
  • 常量表达式;
  • 形如 new ValType() 的表达式,其中 ValType 是值类型,例如枚举或结构体;
  • 形如 default(ValType) 的表达式,其中 ValType 是值类型。
由于 string.Empty 不属于这些类型中的任何一种,因此不允许使用。

http://msdn.microsoft.com/en-us/library/dd264739.aspx


无论哪件事都不是。 - ClickRick

2

默认参数值必须是常量,但String.Empty是只读字段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接