为什么String.Empty是无效的默认参数?

时间:2015-01-20 10:47:43

标签: c# .net parameters optional-parameters compile-time

如果我键入以下内容:

public Response GetArticles(string Filter = String.Empty)
{
    //Body
}

Visual Studio给出了这个错误:

  

“过滤器”的默认参数值必须是编译时常量

如果我将String.Empty更改为经典"",则会修复此问题。

但我仍然对String.Empty及其行为的错误感到好奇。

2 个答案:

答案 0 :(得分:9)

  

为什么String.Empty是无效的默认参数?

因为"'过滤'的默认参数值必须是编译时常量"。 String.Empty不是常数,而只是static readonly。像"Foo"这样的字符串文字是常量作为实现细节(我还没有找到文档)。

进一步阅读:Why isn't String.Empty a constant?

引用自10.4#C#语言规范的常量:

  

readonly关键字与const关键字不同。一个const字段   只能在该字段的声明中初始化。一个只读   字段可以在声明或在声明中初始化   构造函数。因此,只读字段可以具有不同的值   取决于使用的构造函数。此外,虽然const字段是a   编译时常量,readonly字段可用于运行时   常数

根据可选参数,这是MSDN引用:

默认值必须是以下类型的表达式之一:

  • 常量表达
  • 新形式ValType()的表达式,其中ValType是值类型,例如枚举或结构
  • 表单default(ValType)的表达式,其中ValType是值类型。

我很惊讶您可以使用new ValType(),其中ValType是值类型或结构。我不知道您可以使用new DateTime()之类的默认构造函数,但不能使用new DateTime(2015,1,15)。从我自己的回答中学到了新的东西。

答案 1 :(得分:2)

string.Empty不是编译时常量。例如,您可以使用Reflection更改其值。但是""空字符串文字是常量,它的值在编译时是已知的,这就是它有效的原因。