93

我正在阅读Bill Wagner 的《Effective C# 》。Item 14 - Minimize Duplicate Initialization Logic中,他展示了在构造函数中使用新的可选参数功能的以下示例:

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

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

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

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

更新
只是一个后续评论。根据 MSDN:

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

然后我们不能使用System.Environment.NewLine任何一个,或者使用新实例化的对象作为默认值。我还没用过VS2010,这很令人失望!

4

7 回答 7

69

从 C# 2.0 编译器开始,String.Empty无论如何都没有什么意义,事实上在许多情况下这是一种悲观,因为编译器可以内联一些""String.Empty.

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

于 2010-04-23T19:16:55.640 回答
56

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

const string String_Empty = "";

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

[顺便说一句,在其他答案中没有提到的总体上更喜欢String.Empty的一个原因""是,有各种 Unicode 字符(零宽度连接符等)实际上是肉眼看不见的。所以看起来像""的东西不一定是空字符串,而String.Empty你确切地知道你在使用什么。我承认这不是常见的错误来源,但有可能。]

于 2012-02-25T11:12:46.813 回答
26

从原来的问题:

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

空字符串以何种方式因系统而异?它总是一个没有字符的字符串!如果我找到返回 false 的实现,我会非常string.Empty == ""害怕:) 这类似Environment.NewLine.

来自反恐精英的赏金帖:

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

那么这肯定不会发生。

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

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

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

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

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

综上所述:

  • 我非常怀疑这是否会成为 C# 的一部分
  • 因为string.Empty无论如何都是没有意义的
  • 对于其他确实总是具有相同值的值,这真的痛苦
于 2012-03-03T08:27:59.680 回答
7

我从不使用 string.Empty,我看不出它的意义。也许它让那些真正接触编程的人更容易,但我怀疑它是否有用。

于 2010-04-23T19:13:57.583 回答
4

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

于 2010-04-23T19:15:49.040 回答
3

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

public static readonly string Empty

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

于 2012-02-27T15:23:47.537 回答
2

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

如果其他人稍后需要阅读/更改我的代码,他们知道我的意思是检查或将某些内容设置为空字符串。使用 just""有时会导致错误和混乱,因为我可能只是忘记将我想要的字符串放在那里。

例如:

if(someString == string.Empty)
{

}

对比

if(someString == "")
{

}

第一个if陈述对我来说似乎更加深思熟虑和可读。因为这只是一个偏好,我真的没有看到必须使用""而不是string.Empty.

于 2015-06-22T10:52:44.333 回答