将空数组作为可选参数的默认值传递

107

如何定义一个函数,该函数接受一个可选的数组参数,且默认为空数组?

public void DoSomething(int index, ushort[] array = new ushort[] {},
 bool thirdParam = true)

'array'的默认参数值必须是编译时常量。


10
这不是重复内容。它具体询问如何为数组设置默认值,而不是字符串。在方法上有真正的差异。 - user755404
3个回答

160

你无法创建对象引用的编译时常量。

唯一有效的编译时常量是null,因此请将您的代码更改为:

public void DoSomething(int index, ushort[] array = null,
  bool thirdParam = true)

在你的方法内部执行以下操作:

array = array ?? new ushort[0];

(来自评论) 从C# 8开始,您还可以使用更简短的语法:

array ??= new ushort[0];

3
是的,这确实会让人想起来,但传递null并不等同于一个空数组。我希望能找到一种在方法内部不必包装参数的方法。关于对象引用的编译时常量的那一点是有道理的。谢谢! - MandoMando
为什么会抛出 ArgumentNullException?有人知道原因吗? - Ayyash
4
是的,你没有解决实际上接收到"null"的情况,你使用了我答案中的第二个语句吗?(原文已经是英文) - Lasse V. Karlsen
我只想提一下,C# 8 现在允许更漂亮的语法。array ??= new ushort[0]; - Éric Bergeron
也许你可以考虑使用 Array.Empty<ushort>() - Yousef
显示剩余2条评论

30
如果您可以将数组作为最后一个参数,您也可以这样做:
public void DoSomething(int index, bool wasThirdParam = true, params ushort[] array)

编译器会自动传递一个空数组,如果未指定,则可以灵活地将数组作为单个参数传递或将元素直接作为可变长度参数放入方法中。

7

我知道这是一个老问题,虽然这个答案并不能直接解决编译器所施加的限制,但方法重载是一种替代方法:

   public void DoSomething(int index, bool thirdParam = true){
        DoSomething(index, new ushort[] {}, thirdParam);
   }

   public void DoSomething(int index, ushort[] array, bool thirdParam = true){

      ...
   }

我不确定编译器是否能够推断和优化相互递归,而不是通常的*(尽管我知道例如在g++中有一个选项-foptimize-sibling-calls,但它是C++,我不确定C#编译器是否可以)*。 - Hi-Angel

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