Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么params会这样做?_C# - Fatal编程技术网

C# 为什么params会这样做?

C# 为什么params会这样做?,c#,C#,输出 一, 二, 空的 二, 代码 class Program { static void Main(String[] args) { String s = null; PrintLength(s); PrintLength(s, s); PrintLength(null); PrintLength(null, null); Console.ReadKey();

输出

一,

二,

空的

二,

代码

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());
    }    
}
PrintLength(null)
正在传递一个null数组,其中as
PrintLength(null,null)
正在传递一个长度为2的
string[]
,其中包含两个null
string
对象。这与传递
新字符串[]{null,null}

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

编辑:

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


它按设计工作,我想说:

打印长度(s)

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

打印长度(s,s)

这里的情况也一样-您要传入两个元素,因此方法中的
项将是一个由两个字符串组成的数组-这两个字符串本身都为空,但数组不是空的

打印长度(空)

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

打印长度(空,空)

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

这可能有点令人费解,但实际上:您需要在
PrintLength
方法中检查的不是整个
Items
是否为空,而是实际值
Items[0]
等是否为空

一开始可能有点奇怪,或者说有点违反直觉的是,单个显式“null”值被视为“null”,而不是一个值为null的单个项的数组。为什么会出现这种情况,以及它是否可以以不同的方式实施——老实说,我不知道。

正如回答一所说:

  • 1:字符串数组,其中有一个元素-元素为null

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

  • null:null被传递到方法中,而不是数组中

  • 2:将null数组传递到方法中


    • 这是一个相当常见的问题。有关详细信息,请参见本规范第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" });
      
      我们总是选择扩展的形式。这会怎么样?一个对象数组就是一个对象,所以这将选择扩展形式——它将生成另一个数组,将这个东西包装在数组中,然后传递它


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

      我认为问题是,为什么传递一个null不能传递新字符串[]{null}的等价物?这看起来像是某种故意硬编码的行为,但目的是什么有点神秘。Re:edit,所以它解释空值就像传递字符串[]s=null;嗯,有趣的角落案例,很好的帖子,埃里克。我可以加上第一个PrintLength(null),您将向函数传递一个null值,其中与第二个PrintLength示例一样,您传递的是一个字符串指针(reference),它实际上不引用任何内容。然而,引用仍然存在于内存中,值为0,因为它是一个空指针。我90%确定是这样,但10%的人一直在唠叨我。奇怪的是,“扩展形式”实际上是口语中的“收缩形式”