输出
1
2
空
2
代码
class Program
{
static void Main(String[] args)
{
String s = null;
PrintLength(s);
PrintLength(s, s);
PrintLength(null);
PrintLength(null, null);
Console.ReadKey();
}
private static void PrintLength(params String[] items)
{
Console.WriteLine(items == null ? "null" : items.Length.ToString());
}
}
答案 0 :(得分:28)
这是一个经常被问到的问题。有关详细信息,请参阅规范的7.4.1和7.4.3.1节。
简要说明:具有params数组的方法适用于“正常形式”或“扩展形式”。也就是说,你可以说
PrintLength(new string[] {"hello"}); // normal form
PrintLength("hello"); // expanded form, translated into normal form by compiler.
当给出适用于两种形式的调用时,编译器总是在扩展形式上选择普通形式。
假设我们每次都适用时选择了扩展形式。假设你有
void M(params object[] x) {}
如果我们总是选择扩展形式,你如何实际将空数组传递给这个东西?那是不可能的!
假设你说
M(new object[] { "hello" });
我们总是选择扩展形式。这会是什么?好吧,一个对象数组是一个对象,所以这将选择扩展形式 - 它将使另一个数组,将这个东西包装在数组中,并传递它!
选择扩展形式而非正常形式会导致疯狂的结果。总是在扩展形式上选择正常形式是更明智的做法。
答案 1 :(得分:5)
它按设计工作,我会说:
PrintLength(一个或多个);
你传入一个null的单个字符串 - 在你的方法中,items
将不为null - 它是一个元素的数组 - 类型为string - 的值为{ {1}}
PrintLength(s,s);
同样的故事 - 你传递了两个元素,所以你的方法中的null
将是一个包含两个字符串的数组 - 这两个字符串本身都是null,但数组不是
PrintLength(空);
这显然被解释为单个NULL值,因此items
为空。你没有传入一个数组,也没有传入一个string类型的元素 - 你只是传递一个空值。
PrintLength(null,null);
这又是一个两个元素的数组,两个元素都是null - 但是数组本身不是null,因为你传递了两个值。
这可能有点令人费解 - 但实际上:您需要在items
方法中检查的不是您的PrintLength
整体是否为空 - 而是实际值{{1等等是空的。
有点奇怪 - 或者首先是反直觉 - 是将单个显式“null”值视为“null” - 而不是单个null值项的数组。为什么会这样,以及它是否可以采用不同的方式实施 - 我不知道,老实说。
答案 2 :(得分:4)
PrintLength(null)
传递一个空数组,其中PrintLength(null, null)
传递的string[]
长度为2,包含两个空string
个对象。它与传递new string[] { null, null }
嗯读我写的内容可能实际上并没有回答你的问题耸肩。
修改:
这可能是原因:您可以发送以逗号分隔的参数声明中指定类型的参数列表,或者指定类型的参数数组。
答案 3 :(得分:0)
如答案一所述:
1:包含一个元素的字符串数组 - 元素为空
2:包含两个元素的字符串数组,两个元素都为空
null:null传递给方法,而不是数组
2:将一个空数组传递给方法