产量
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());
}
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 29
这是一个经常被问到的问题.有关详细信息,请参阅规范的7.4.1和7.4.3.1.
简而言之:具有params数组的方法适用于其"正常形式"或其"扩展形式".也就是说,你可以说
PrintLength(new string[] {"hello"}); // normal form
PrintLength("hello"); // expanded form, translated into normal form by compiler.
Run Code Online (Sandbox Code Playgroud)
当给出适用于两种形式的调用时,编译器总是在扩展形式上选择普通形式.
假设我们每次都适用时选择扩展形式.假设你有
void M(params object[] x) {}
Run Code Online (Sandbox Code Playgroud)
如果我们总是选择扩展形式,你会如何实际将空数组传递给这个东西?那是不可能的!
假设你说
M(new object[] { "hello" });
Run Code Online (Sandbox Code Playgroud)
我们总是选择扩展形式.这会是什么?好吧,一个对象数组是一个对象,所以这将选择扩展形式 - 它将创建另一个数组,将这个东西包装在数组中,并传递它!
扩展形式超过正常形式的选择导致疯狂的结果.总是在扩展形式上选择正常形式是更明智的做法.
我按照设计工作,我会说:
PrintLength(一个或多个);
你正在传递一个字符串,它是空-你的方法里面,items会不会为空-这是一个元素的数组-字符串类型-价值null
PrintLength(s,s);
同样的故事在这里 - 你传递了两个元素,所以items在你的方法中将是一个由两个字符串组成的数组 - 这两个字符串本身都是null,但数组不是
PrintLength(NULL);
这显然被解释为单个NULL值,因此items为null.你没有传入一个数组,也没有传入一个string类型的元素 - 你只是传入一个空值本身.
PrintLength(null,null);
这又是一个由两个元素组成的数组,两个元素都是null - 但是数组本身不是null,因为你传递了两个值.
这可能有点令人费解 - 但实际上:你需要在你的PrintLength方法中检查的不是你Items的整体是否为空 - 而是实际值是否items[0]为空.
可能有点奇怪 - 或者首先是反直觉 - 是将单个显式"null"值视为"null" - 而不是单个null值项的数组.为什么会这样,以及它是否可以以不同的方式实施 - 我不知道,老实说.