代码之家  ›  专栏  ›  技术社区  ›  Serhat Ozgel

如何将单个对象[]传递给params对象[]

  •  112
  • Serhat Ozgel  · 技术社区  · 16 年前

    我有一个方法,它接受params对象[],例如:

    void Foo(params object[] items)
    {
        Console.WriteLine(items[0]);
    }
    

    当我将两个对象数组传递给此方法时,它工作正常:

    Foo(new object[]{ (object)"1", (object)"2" }, new object[]{ (object)"3", (object)"4" } );
    // Output: System.Object[]
    

    但当我传递单个对象[]时,它不会将我的对象[]作为第一个参数,而是采用它的所有元素,就像我想逐个传递它们一样:

    Foo(new object[]{ (object)"1", (object)"2" });
    // Output: 1, expected: System.Object[]
    

    如何将单个对象[]作为第一个参数传递给params数组?

    7 回复  |  直到 6 年前
        1
  •  89
  •   Undo ptrk    7 年前

    一个简单的类型转换将确保编译器知道您在这种情况下的意思。

    Foo((object)new object[]{ (object)"1", (object)"2" }));
    

    因为数组是对象的子类型,所以这一切都可以解决。不过有点奇怪,我同意。

        2
  •  67
  •   Community CDub    7 年前

    这个 params 参数修饰符为调用方提供了向方法传递多个参数的快捷语法。有两种方法可以用 帕拉姆 参数:

    1) 使用参数类型的数组调用,在这种情况下, 帕拉姆 关键字无效,数组直接传递给方法:

    object[] array = new[] { "1", "2" };
    
    // Foo receives the 'array' argument directly.
    Foo( array );
    

    2) 或者,使用扩展的参数列表调用,在这种情况下,编译器将自动将参数列表包装在临时数组中,并将其传递给方法:

    // Foo receives a temporary array containing the list of arguments.
    Foo( "1", "2" );
    
    // This is equivalent to:
    object[] temp = new[] { "1", "2" );
    Foo( temp );
    


    为了将对象数组传递给 params object[] “参数,您可以:

    1) 如前所述,手动创建包装数组并将其直接传递给方法 lassevk :

    Foo( new object[] { array } );  // Equivalent to calling convention 1.
    

    2) 或者,把论点投射到 object ,如前所述 Adam ,在这种情况下,编译器将为您创建包装数组:

    Foo( (object)array );  // Equivalent to calling convention 2.
    


    但是,如果该方法的目标是处理多个对象数组,则使用显式 params object[][] “参数”。这将允许您将多个数组作为参数传递:

    void Foo( params object[][] arrays ) {
      foreach( object[] array in arrays ) {
        // process array
      }
    }
    
    ...
    Foo( new[] { "1", "2" }, new[] { "3", "4" } );
    
    // Equivalent to:
    object[][] arrays = new[] {
      new[] { "1", "2" },
      new[] { "3", "4" }
    };
    Foo( arrays );
    

    编辑: Raymond Chen在中描述了这种行为以及它与C规范的关系。 a new post .

        3
  •  7
  •   ACOMIT001    9 年前

    这是一个涉及LINQ的单行解决方案。

    var elements = new String[] { "1", "2", "3" };
    Foo(elements.Cast<object>().ToArray())
    
        4
  •  3
  •   Lasse V. Karlsen    16 年前

    您需要将它封装到另一个对象[]数组中,如下所示:

    Foo(new Object[] { new object[]{ (object)"1", (object)"2" }});
    
        5
  •  1
  •   Mike Stone    16 年前

    一个选项是可以将其包装到另一个数组中:

    Foo(new object[]{ new object[]{ (object)"1", (object)"2" } });
    

    有点难看,但由于每个项目都是一个数组,所以您不能只是将其强制转换为使问题消失…例如,如果它是foo(params object items),则可以执行以下操作:

    Foo((object) new object[]{ (object)"1", (object)"2" });
    

    或者,您可以尝试定义另一个重载的foo实例,它只使用一个数组:

    void Foo(object[] item)
    {
        // Somehow don't duplicate Foo(object[]) and
        // Foo(params object[]) without making an infinite
        // recursive call... maybe something like
        // FooImpl(params object[] items) and then this
        // could invoke it via:
        // FooImpl(new object[] { item });
    }
    
        6
  •  1
  •   sth    12 年前
    new[] { (object) 0, (object) null, (object) false }
    
        7
  •  1
  •   Zhuravlev A.    6 年前

    解决这个问题的另一种方法(这不是很好的做法,但看起来很美):

    static class Helper
    {
        public static object AsSingleParam(this object[] arg)
        {
           return (object)arg;
        }
    }
    

    用途:

    f(new object[] { 1, 2, 3 }.AsSingleParam());