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

时间:2010-04-23 19:11:06

标签: c# c#-4.0 optional-parameters

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

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

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

  

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

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

UPDATE
只是后续评论。根据MSDN:

  

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

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

8 个答案:

答案 0 :(得分:58)

从C#2.0编译器开始,无论如何都很少指向String.Empty,事实上在很多情况下它是一种悲观,因为编译器可以内联对""的一些引用但不能对String.Empty执行相同操作。

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

答案 1 :(得分:52)

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

const string String_Empty = "";

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

[顺便说一句,一般来说,String.Empty优于""的一个原因是,在其他答案中没有提到,是有各种Unicode字符(零宽度连接符,肉眼看不见的。所以看起来像""的东西不一定是空字符串,而使用String.Empty你确切地知道你正在使用什么。我知道这不是bug的常见来源,但它是可能的。]

答案 2 :(得分:24)

从最初的问题:

  

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

空字符串以何种方式因系统而异?它总是一个没有字符的字符串!如果我找到string.Empty == ""返回false的实现,那我真的害怕这是 not Environment.NewLine相同。

来自Counter Terrorist的赏金帖子:

  

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

那肯定不会发生。

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

string.Empty {em> 毫无意义 - 使用""会做你想要的事情;是 使用字符串文字是痛苦的吗? (我到处使用文字 - 我从不使用string.Empty - 但这是一个不同的论点。)

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

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

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

总结:

  • 我非常怀疑这将成为C#
  • 的一部分
  • 对于string.Empty来说,无论如何都是毫无意义的
  • 对于其他总是具有相同值的值,

答案 3 :(得分:7)

我从不使用string.Empty,我看不出它的意义。也许这对于那些对编程很不熟悉的人来说更容易,但我怀疑它甚至对此有用。

答案 4 :(得分:4)

我认为string.Empty背后的想法是增强可读性。它与newline不同,它在不同平台上的表示方式有何不同。它很as它不能在默认参数中使用。但是,如果您在Windows和Linux上的Mono之间移植,它不会导致任何问题。

答案 5 :(得分:3)

作为一个FYI,看起来对传递给属性构造函数的值施加了相同的约束 - 它们必须是常量。由于string.empty定义为:

public static readonly string Empty

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

答案 6 :(得分:1)

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

如果其他人需要稍后阅读/更改我的代码,他们知道我打算检查或设置一些空字符串。仅使用""有时可能会导致错误和混乱,因为我可能忘了把我想要的字符串放在那里。

例如:

if(someString == string.Empty)
{

}

VS

if(someString == "")
{

}

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

答案 7 :(得分:-2)

这个问题的最佳解决方案可能就是这种方法的重载:

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