不能使用String.Empty作为可选参数的默认值

我正在阅读Bill Wagner的Effective C# 。 在项目14 – 最小化重复初始化逻辑 ,他显示了在构造函数中使用新的可选参数function的以下示例:

public MyClass(int initialCount = 0, string name = "")

注意他用""而不是string.Empty
他评论说:

你会注意到[在上面的例子中]第二个构造函数指定name参数的默认值,而不是更习惯的string.Empty 。 这是因为string.Empty不是一个编译时常量。 它是一个在string类中定义的静态属性。 因为它不是一个编译常量,所以不能用它作为参数的默认值。

如果我们不能在所有情况下都使用string.Empty静态,那么这不就是它的目的吗? 我认为我们会用它来确保我们有一个与系统无关的方式来引用空string。 我的理解错了吗? 谢谢。

UPDATE
只是跟进评论。 根据MSDN:

每个可选参数都有一个默认值作为其定义的一部分。 如果没有为该参数发送参数,则使用默认值。 默认值必须是常量。

那么我们无法使用System.Environment.NewLine ,或者使用新实例化的对象作为默认值。 我还没有使用VS2010,这是令人失望的!

就C#2.0编译器而言, String.Empty实际上在很多情况下是非常悲观的,因为编译器可以内联一些对""引用,但不能对String.Empty执行相同的操作。

在C#1.1中,避免创build大量包含空string的独立对象是很有用的,但那些日子已经过去了。 ""工作得很好。

如果你真的想把它用作可选的参数值,没有什么可以阻止你为空string定义自己的常量:

 const string String_Empty = ""; public static void PrintString(string s = String_Empty) { Console.WriteLine(s); } 

[另一方面,一般来说比较喜欢String.Empty一个原因是,在其他答案中没有提到,有很多Unicode字符(零宽度的join者等),这些字符是不可见的肉眼。 所以看起来像""东西不一定是空string,而用String.Empty你确切地知道你在用什么。 我认识到这不是错误的常见来源,但它是可能的。]

从原来的问题来看:

我认为我们会用它来确保我们有一个与系统无关的方式来引用空string。

空string在不同的系统中可以以什么方式变化? 它总是一个没有字符的string! 我真的很害怕,如果我发现了一个实现在string.Empty == ""返回false :)这不是Environment.NewLine一样。

从反恐怖主义的恩惠post:

我希望String.Empty可以用作下一个C#版本的默认参数。 :d

那么这肯定不会发生。

虽然我个人也喜欢一个非常不同的默认机制,但可选参数的工作方式从一开始就是在.NET中的,它总是意味着在元数据中embedded一个常量,以便调用代码可以将该常量复制到调用中网站如果没有提供相应的参数。

string.Empty真的没有意义 – 用""会做你想做的; 是使用string文字痛苦的吗? (我在任何地方使用文字 – 我从不使用string.Empty – 但这是一个不同的论点。)

这就是令我感到意外的一个问题 – 抱怨是围绕一些并不真正导致真正问题的东西。 在需要在执行时计算默认值的情况下更重要,因为实际上可能会有所不同。 例如,我可以想象一下,您希望能够使用DateTime参数调用方法,并使其默认为“当前时间”。 目前,我所知道的唯一隐约优雅的解决方法是:

 public void RecordTime(string message, DateTime? dateTime = null) { var realDateTime = dateTime ?? DateTime.UtcNow; } 

…但这并不总是合适的。

结论是:

  • 我非常怀疑这将是C#的一部分
  • 对于string.Empty无论如何毫无意义
  • 对于其他价值观来说, 它们并不总是具有相同的价值,这确实是一种痛苦

我从不使用string.Empty,我看不到它的重点。 也许这会让那些对编程真的很陌生的人变得更容易,但是我怀疑这是否有用。

我认为string.Empty背后的想法是增强可读性。 它不像新线,它在不同的平台上performance出来有什么区别。 这是不好的,它不能用于默认参数。 但是,如果您在Windows和Mono之类的软件之间移植,则不会引起任何问题。

作为参考,似乎对传递给属性构造函数的值施加了相同的约束 – 它们必须是不变的。 由于string.empty被定义为:

 public static readonly string Empty 

而不是一个实际的常数,它不能被使用。

如果你真的不喜欢string文字,你可以使用:

 public static string MyFunction(string myParam= default(string)) 

我使用string.Empty纯粹是为了可读性。

如果其他人需要稍后阅读/更改我的代码,他们知道我打算检查或设置一个空string。 使用""有时会引起错误和混淆,因为我可能忘了把string放在那里。

例如:

 if(someString == string.Empty) { } 

VS

 if(someString == "") { } 

第一个if语句对我来说似乎更加审慎和可读。 因为这只是一个偏好,我真的没有看到火车粉碎必须使用""而不是string.Empty

也许这个问题的最佳解决scheme是这种方法的重载,这样:

 public static void PrintString() { PrintString(string.Empty); }