【问题标题】:Advanced Optional Parameters (c#) [duplicate]高级可选参数(c#)[重复]
【发布时间】:2011-07-20 11:32:12
【问题描述】:

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

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

下一个最好的选择是做

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

【问题讨论】:

  • 它会产生什么错误。这将为您提供有关它为什么不起作用的线索。
  • @ChrisF,'bar' 的默认参数值必须是编译时常量

标签: c# optional-parameters


【解决方案1】:

不,这是不可能的。默认值需要是编译时常量。默认值将被插入调用者,而不是被调用者。如果调用者无法访问用于创建您的默认值的方法,您的代码将是一个问题。

但是你可以使用简单的重载:

public void foo(char[] bar)
{
}

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

【讨论】:

    【解决方案2】:

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

    Why do optional parameters in C# 4.0 require compile-time constants?

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 吹毛求疵:字符串是引用类型,void M(string s = "hello") {} 是完全合法的!
      • @LukeH:确实如此,但 .NET 的架构师已经竭尽全力掩盖这一事实,并使字符串表现得像一个值类型。 string 在各种 .NET 概念中绝对是一个例外。
      【解决方案4】:

      其他 cmets 也适用,但也要考虑到,由于默认值是在编译时插入到调用者中的,因此在以后更改默认值不会更改调用者代码中的值(假设它是从另一个程序集。)因此,您提出的解决方法或次佳选项实际上是更好的做法.

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 这个关于值类型的断言是错误的。 void foo(DateTime x = new DateTime(2011,3,22)){} 编译失败。您可以使用的是编译时常量
        猜你喜欢
        • 2012-01-03
        • 1970-01-01
        • 1970-01-01
        • 2010-12-16
        • 2019-06-24
        • 2015-04-12
        • 1970-01-01
        • 2015-11-25
        • 1970-01-01
        相关资源
        最近更新 更多