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

Mik*_*g36 87 c# optional-parameters c#-4.0

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

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

请注意,他使用""而不是string.Empty.
他评论道:

您将注意到[在上面的示例中]第二个构造函数为name参数指定了默认值,而不是更常用的string.Empty.那是因为string.Empty它不是编译时常量.它是字符串类中定义的静态属性.因为它不是编译常量,所以不能将它用作参数的默认值.

如果我们不能string.Empty在所有情况下使用静态,那么这不是打败了它的目的吗?我认为我们会用它来确保我们有一个独立于系统的方法来引用空字符串.我的理解错了吗?谢谢.

更新
只是后续评论.根据MSDN:

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

然后我们无法使用它们System.Environment.NewLine,或者使用新实例化的对象作为默认值.我还没有用过VS2010,这太令人失望了!

And*_*mer 62

从C#2.0编译器开始,String.Empty无论如何都没有什么意义,事实上在很多情况下它是一种悲观,因为编译器可以内联一些引用,""但不能做同样的事情String.Empty.

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

  • 我发现使用String.Empty快速识别空字符串要比在""处查看两次更容易,以确保它没有隐藏在其中的撇号或类似内容.虽然+1的解释. (14认同)
  • +1克里斯.同样在VS中,你真的无法搜索""的用法(除了执行标准的查找,它还会带回每个文本匹配,包括注释和标记).您可以使用string.Empty搜索特定于代码的用法. (11认同)
  • 即使在.NET 1.1中,它也不会创建"大量"的独立对象.我不记得1.1和2.0之间在这方面的差异的细节,但它不像字符串文字实习仅在2.0中引入. (7认同)

Mat*_*dge 53

如果您真的想将它用作可选参数值,那么没有什么可以阻止您为空字符串定义自己的常量:

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}
Run Code Online (Sandbox Code Playgroud)

[顺便说一句,一个理由,更喜欢String.Empty""在一般情况下,还没有在其他的答案所提到的,是有各种Unicode字符(零宽度加入者等),其是有效不可见的肉眼.所以看起来""不一定是空字符串,而String.Empty你知道你正在使用什么.我知道这不是bug的常见来源,但它是可能的.]

  • +1.你让"String.Empty"看起来像是有目的的! (16认同)
  • 还有不可见的标识符字符,因此看起来像String_Empty的东西不一定.Unicode标准在很大程度上忽略了有关安全性考虑的章节. (2认同)

Jon*_*eet 24

从原来的问题:

我认为我们会用它来确保我们有一个独立于系统的方法来引用空字符串.

空字符串以何种方式因系统而异?它总是一个没有字符的字符串!我是真的害怕,如果我没有发现其中的实现string.Empty == ""返回false :)这是一样的东西一样Environment.NewLine.

来自Counter Terrorist的赏金帖子:

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

那肯定不会发生.

虽然我本人也喜欢一种非常不同的默认机制,但是自从开始以来,可选参数的工作方式一直在.NET中 - 它总是意味着将一个常量嵌入到元数据中,这样调用代码就可以将该常量复制到调用中如果没有提供相应的参数,则为site.

有了string.Empty真的毫无意义-使用""会做你想要的东西; 是不是那个痛苦的使用字符串文字?(我到处使用文字 - 我从不使用string.Empty- 但这是一个不同的论点.)

这就是我对这个问题感到惊讶的事情 - 抱怨围绕着一些实际上并没有引起真正问题的事情.在您希望在执行时计算默认值的情况下更重要,因为它实际上可能会有所不同.例如,我可以想象您希望能够使用DateTime参数调用方法并将其默认为"当前时间"的情况.目前,我所知道的唯一模糊优雅的解决方法是:

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

......但这并不总是合适的.

结论:

  • 我非常怀疑这将成为C#的一部分
  • 因为string.Empty它无论如何都是毫无意义的
  • 对于其他值这确实总是具有相同的值,它真的可以是一个痛苦


Han*_*son 7

我从不使用string.Empty,我看不出它的重点.也许这对于那些真正对编程很新的人来说更容易,但我怀疑它对于那些来说是有用的.

  • 我建议任何不能区分它们的人需要更好的眼镜或降低屏幕的分辨率.我的视力不好,我记不起犯了这个错误(而且我必须使用包含两者的很多代码). (8认同)
  • 也许它可以防止混淆`""和``"`,但我不能说``"`就是这么常见. (2认同)
  • string.Empty有助于找出程序员的确切意图。“”没有说明任何意图,如果程序员的意图是像这样“ lol”那样初始化变量,但忘了...在这种情况下,存在无穷的可能性和字符串,Empty派上用场并做得更好 (2认同)