C# 4.0:方法参数默认值作为数组

6

C# 4.0是否支持将方法参数的默认值设置为数组(例如string[] sArray)?如果支持,如何实现?

我尝试像下面这样调用函数:

MethodA(string[] legends=new string[]{"a","b"},float[] values=new float[]{1,2}, string alt="sd");

它不能工作。

2个回答

10

正如其他人所说,默认值不能为数组。然而,避免这个问题的一种方法是将默认值设为null,然后在必要时初始化数组:

public void Foo(int[] x = null)
{
    x = x ?? new int[] { 5, 10 };
}

或者,如果您不会改变数组的内容或将其暴露给调用者:

private static readonly int[] FooDefault = new int[] { 5, 10 };
public void Foo(int[] x = null)
{
    x = x ?? FooDefault;
}
请注意,这假定 null 不是你想以其他原因使用的值。这不是一种全局适用的想法,但在某些情况下效果很好,例如你无法将默认值表达为编译时常量。你可以用同样的方法来设置像 Encoding.UTF8 这样的东西作为默认编码。
如果你想要一个值类型参数,你可以将其设为可空类型。例如,假设你想将参数默认值设置为处理器数量(显然不是编译时常量),你可以这样做:
public void RunInParallel(int? cores = null)
{
    int realCores = cores ?? Environment.ProcessorCount;
}

3

默认值必须是编译时常量,这意味着不能使用数组。

标准(第312页)如下所述:

默认参数中的表达式必须是以下之一:

  • 常量表达式
  • 形式为 new S() 的表达式,其中 S 是值类型
  • 形式为 default(S) 的表达式,其中 S 是值类型

1
@Graphain:除了空数组之外,任何数组都是常量吗?非空数组始终是可变的。编译器必须在每次调用时创建数组的副本,以防某些内容(例如被调用的方法)已更改。 - Jon Skeet
2
@Graphain:不存在只读数组这样的东西。那该方法是否不能将其传递给任何需要数组参数的其他内容?你说的基本上是一个不同的类型。 - Jon Skeet
@Jon Skeet,我的错误。但是它并不意味着你不能使用只读的IEnumerable类型,对吧? - Matt Mitchell
@Graphain:这一点并不是随意的。默认值机制已经存在很长时间了,只是C#现在将其公开。不要低估调用者无需指定值的价值。试着在保存Word文档之前和之后尝试一下...我更喜欢指定2个值而不是18个。一个“从头开始”的设计可能会有所不同,但这里有非常古老的限制。 - Jon Skeet
@Jon Skeet - 我总是忘记一些遗留的和 COM API 有多糟糕,而且忘记它们并没有进行 IL 更改,只是 C# 更改。感谢您一如既往的启示。 - Matt Mitchell
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接