高级可选参数(c#)

高级可选参数(c#),c#,optional-parameters,C#,Optional Parameters,下面的代码如果能工作的话会很酷。但是,我无法编译它,所以我假设这在任何形式下都不起作用 public void foo(char[] bar = new char[]{'a'}) { } 下一个最好的选择就是这样做 public void foo(char[] bar = null) { if (bar==null) bar = new {'a'}; } 否,因为可选参数默认值需要为常量 不,这是不可能的。默认值必须是编译时常量。默认值将插入调用者,而不是被调用者。如果调用

下面的代码如果能工作的话会很酷。但是,我无法编译它,所以我假设这在任何形式下都不起作用

public void foo(char[] bar = new char[]{'a'})
{
}
下一个最好的选择就是这样做

public void foo(char[] bar = null)
{
   if (bar==null)
      bar = new {'a'};
}

否,因为可选参数默认值需要为常量


不,这是不可能的。默认值必须是编译时常量。默认值将插入调用者,而不是被调用者。如果调用方无法访问用于创建默认值的方法,则代码将出现问题

但您可以使用简单的重载:

public void foo(char[] bar)
{
}

public void foo()
{
  foo(new char[]{'a'});
}

这永远不会起作用,因为char[]不是值类型,而是引用类型。只有值类型才能在可选参数中为其指定常量。在编译时不能有对对象(如数组)的引用。(Null是可选引用类型的唯一有效值。)

只有在值类型中,才可以将参数的默认值设置为编译时常量(使其成为可选值)。对于引用类型,只有字符串具有该功能。其他类型只能设置为null


编辑:感谢@Martinho Fernandes指出这一点。对于值类型,只允许编译时常数

也适用于其他注释,但也要考虑到,因为默认值在编译时插入到调用方中,所以在稍后的某个时间更改默认值不会改变调用方代码中的值(假设它是从另一个程序集调用的)。您提出的解决方案或次优选项实际上是一种更好的实践。

它会产生什么错误。这将为您提供有关它为什么不起作用的线索。@ChrisF,“bar”的默认参数值必须是编译时常量此关于值类型的断言为false
void foo(DateTime x=new DateTime(2011,3,22)){}
无法编译。您可以使用的是编译时常量。一个挑剔:字符串是引用类型,
void M(string s=“hello”){}
是完全合法的@LukeH:这是真的,但是.NET的架构师已经竭尽全力掩盖了这一事实,并使字符串的行为类似于值类型。字符串绝对是各种.NET概念中的一个例外。