为什么将null传递给params方法导致null参数数组?

Fis*_*rdo 30 .net c# params .net-3.5

我有一个使用params关键字的方法,如下所示:

private void ParamsMethod(params string[] args)
{
    // Etc...
}
Run Code Online (Sandbox Code Playgroud)

然后,我使用各种参数组合调用该方法:

                            // Within the method, args is...
ParamsMethod();             // - a string array with no elements
ParamsMethod(null);         // - null (Why is this?)
ParamsMethod((string)null); // - a string array with one element: null
ParamsMethod(null, null);   // - a string array with two elements: null and null
ParamsMethod("s1");         // - a string array with one element: "s1"
ParamsMethod("s1", "s2");   // - a string array with two elements: "s1" and "s2"
Run Code Online (Sandbox Code Playgroud)

我了解所有情况,除了第二个.有人能解释为什么ParamsMethod(null)会导致argsnull,而不是用一个空元素的数组?

Jon*_*eet 30

params参数只是为了提供指定值的一个方便的方式-你仍然可以直接传递数组引用.

现在,null可转换为两种string[]string,所以两种解释都是有效的-它是由这是首选的规范.该规范在第10.6.1.4节中指出:

  • 为参数数组提供的参数可以是可隐式转换为参数数组类型的单个表达式.在这种情况下,参数数组的作用就像一个值参数.

  • 或者,[...]

换句话说,编译器首先检查参数是否有效作为"普通"参数类型,并且只有在绝对必须时才构建数组.

  • 此外,值得注意的是,许多采用参数数组的方法也会对(对象),(对象,对象)和(对象,对象,对象)进行重载 - 这是为了避免仅构造数组对象的开销一些对象,因为这些重载将首先匹配. (4认同)

Joe*_*oey 8

请参阅C#规范,第10.6.1.4参数数组:

参数数组允许在方法调用中以两种方式之一指定参数:

  • 为参数数组提供的参数可以是可隐式转换(第6.1节)到参数数组类型的单个表达式.在这种情况下,参数数组的作用就像一个值参数.
  • 或者,调用可以为参数数组指定零个或多个参数,其中每个参数是一个可隐式转换(第6.1节)到参数数组的元素类型的表达式.在这种情况下,调用创建参数数组类型的实例,其长度对应于参数的数量,使用给定的参数值初始化数组实例的元素,并使用新创建的数组实例作为实际参数.

由于null可以隐式转换为string[],因此它将用作数组.

此外:

执行重载解析时,带参数数组的方法可以以其正常形式或以其扩展形式(第7.5.3.1节)应用.只有在方法的正常形式不适用且仅与扩展形式具有相同签名的方法尚未在同一类型中声明时,方法的扩展形式才可用.

这说明编译器在尝试将参数用作数组元素(扩展形式)之前,确实首先尝试将该方法与数组参数(普通形式)一起使用.