代码之家  ›  专栏  ›  技术社区  ›  ChaosPandion

为什么参数的行为是这样的?

c#
  •  22
  • ChaosPandion  · 技术社区  · 15 年前

    产量

    无效的

    代码

    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());
        }    
    }
    
    4 回复  |  直到 15 年前
        1
  •  28
  •   Eric Lippert    15 年前

    这是一个相当常见的问题。详见本规范第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" });
    

    我们总是选择扩展的形式。这能做什么?好吧,一个对象数组是一个对象,所以这将选择扩展的形式——它将 另一个 数组,把这个东西包装在数组中,然后传递给它!

    选择扩展形式而不是普通形式会导致疯狂的结果。总是选择普通形式而不是扩展形式是更明智的做法。

        2
  •  5
  •   marc_s    15 年前

    它按设计工作,我想说:

    打印长度(s);

    您正在传入一个空字符串-在您的方法中, items 为空-它是一个值为字符串类型的元素数组 null

    打印长度(s,s);

    这里是同一个故事-你传递了两个元素,所以 项目 在您的方法中,将是一个由两个字符串组成的数组,这两个字符串本身都为空,但数组不是空的。

    打印长度(空);

    这显然被解释为一个空值,因此 项目 是空的。您不需要传入数组,也不需要传入字符串类型的元素——您只需要本身传入一个空值。

    打印长度(空,空);

    这也是一个由两个元素组成的数组,两个元素都为空,但数组本身不是空的,因为您要传递两个值。

    这可能有点让人困惑,但实际上:你需要检查的是 PrintLength 方法不是 Items 整体上是空的-但是 items[0] 等等都是无效的。

    有点奇怪的是,一开始可能是反直觉的,一个显式的“空”值被视为“空”,而不是一个值为空的单个项的数组。为什么会这样,以及它是否可以以不同的方式实施——我不知道,说实话。

        3
  •  4
  •   Cory Charlton    15 年前

    这个 PrintLength(null) 正在传递一个空数组,其中as PrintLength(null, null) 正在通过 string[] 长度为2,包含两个空值 string 物体。就跟传球一样 new string[] { null, null }

    嗯,我读了我写的东西,也许这并不能回答你的问题。 耸肩 .

    编辑:

    这可能就是为什么: 可以发送一个逗号分隔的参数声明中指定类型的参数列表,或指定类型的参数数组。

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

        4
  •  0
  •   spookycoder    15 年前

    如回答一所述:

    • 1:包含一个元素的字符串数组-元素为空

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

    • 空:向方法传递的是空值,而不是数组

    • 2:向方法传递一个空数组