不能使用String.Empty作为可选参数的默认值
我正在阅读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,这是令人失望的!
就C#2.0编译器而言,无论如何String.Empty
没有什么意义,事实上在很多情况下这是一种悲观,因为编译器可以内联一些对""
引用,但不能对String.Empty
执行相同的操作。
在C#1.1中,避免创建大量包含空字符串的独立对象是很有用的,但那些日子已经过去了。 ""
工作得很好。
如果您真的想将它用作可选参数值,没有什么可以阻止您为空字符串定义自己的常量:
const string String_Empty = "";
public static void PrintString(string s = String_Empty)
{
Console.WriteLine(s);
}
[顺便说一句,一个理由,更喜欢String.Empty
超过""
在一般情况下,还没有在其他的答案所提到的,是有各种Unicode字符(零宽度加入者等),其是有效地不可见的肉眼。 因此,看起来像""
东西不一定是空字符串,而用String.Empty
你确切地知道你在用什么。 我认识到这不是bug的常见来源,但它是可能的。]
从原来的问题来看:
我认为我们会用它来确保我们有一个与系统无关的方式来引用空字符串。
空字符串在不同的系统中以何种方式变化? 它总是一个没有字符的字符串! 如果我发现一个string.Empty == ""
返回false的实现,我会非常害怕。这与Environment.NewLine
类似。
从反恐怖主义的悬赏帖子:
我希望String.Empty可以用作下一个C#版本的默认参数。 :d
那肯定不会发生。
尽管我本人也喜欢一种截然不同的违约机制,但是可选参数的工作方式从一开始就已经在.NET中了 - 它总是意味着在元数据中嵌入常量,以便调用代码可以将该常量复制到调用中网站,如果没有提供相应的参数。
随着string.Empty
它真的没有意义 - 使用""
将做你想要的; 使用字符串文字很痛苦吗? (我在任何地方都使用字面 - 我从来不使用string.Empty
- 但这是一个不同的论点。)
这让我感到意外 - 这个投诉是围绕一些并不真正导致真正问题的东西展开的。 如果您希望在执行时计算默认值,那么它更重要,因为它实际上可能会有所不同。 例如,我可以想象出您希望能够使用DateTime
参数调用方法的情况,并使其默认为“当前时间”。 目前,我所知道的唯一隐约优雅的解决方法是:
public void RecordTime(string message, DateTime? dateTime = null)
{
var realDateTime = dateTime ?? DateTime.UtcNow;
}
......但这并不总是合适的。
结论是:
string.Empty
无论如何都毫无意义 上一篇: Cannot use String.Empty as a default value for an optional parameter