为什么params表现得像这样?

产量

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()); } } 

这是一个经常被问到的问题。 有关详细信息,请参阅规范的7.4.1和7.4.3.1。

简而言之:具有params数组的方法适用于其“正常forms”或其“扩展forms”。 也就是说,你可以说

 PrintLength(new string[] {"hello"}); // normal form PrintLength("hello"); // expanded form, translated into normal form by compiler. 

当给出适用于两种forms的调用时,编译器总是在扩展forms上选择普通forms。

假设我们每次都适用时选择扩展forms。 假设你有

 void M(params object[] x) {} 

如果我们总是选择扩展forms,你会如何实际将空数组传递给这个东西? 那是不可能的!

假设你说

 M(new object[] { "hello" }); 

我们总是选择扩展forms。 这会是什么? 好吧,一个对象数组是一个对象,所以这将选择扩展forms – 它将创建另一个数组,将这个东西包装在数组中,并传递它!

扩展forms超过正常forms的选择导致疯狂的结果。 总是在扩展forms上选择正常forms是更明智的做法。

我按照设计工作,我会说:

PrintLength(一个或多个);

你传入一个null的单个字符串 – 在你的方法中, items 不会为null – 它是一个元素的数组 – 类型为string – 值为null

PrintLength(s,s);

同样的故事 – 你传递了两个元素,所以你的方法中的items将是一个包含两个字符串的数组 – 这两个字符串本身都是null,但数组不是

PrintLength(NULL);

这显然被解释为单个NULL值,因此items为null。 你没有传入一个数组,也没有传入一个string类型的元素 – 你只是传入一个空值本身。

PrintLength(null,null);

这又是一个由两个元素组成的数组,两个元素都是null – 但是数组本身不是null,因为你传递了两个值。

这可能有点令人费解 – 但实际上:你需要在PrintLength方法中检查的不是你的Items是否为null – 而是实际值items[0]等是否为null。

可能有点奇怪 – 或者首先是反直觉 – 是将单个显式“null”值视为“null” – 而不是单个null值项的数组。 为什么会这样,以及它是否可能以不同的方式实施 – 我不知道,老实说。

PrintLength(null)传递一个空数组,其中PrintLength(null, null)传递一个长度为2的string[] ,其中包含两个空string对象。 它与传递new string[] { null, null }

嗯读我写的东西可能实际上并没有回答你的问题耸耸肩

编辑:

这可能是原因: 您可以发送以逗号分隔的参数声明中指定类型的参数列表,或者指定类型的参数数组。

http://msdn.microsoft.com/en-us/library/w5zay9db.aspx

如答案一所述:

  • 1:包含一个元素的字符串数组 – 该元素为null

  • 2:包含两个元素的字符串数组,两个元素都为null

  • null:null传递给方法,而不是数组

  • 2:将一个空数组传递给该方法