【问题标题】:How to pass a single object[] to a params object[]如何将单个对象 [] 传递给参数对象 []
【发布时间】:2010-09-07 08:56:33
【问题描述】:

我有一个采用参数 object[] 的方法,例如:

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[]

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

【问题讨论】:

    标签: c# arrays


    【解决方案1】:

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

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

    由于数组是对象的子类型,这一切都可以解决。虽然有点奇怪的解决方案,但我会同意。

    【讨论】:

    • params 的工作方式似乎没有必要,而且考虑到我们已经习惯于其他语言的 c# 设计,这也是次优的。可以使 params 只接受一种形式,并且可以添加类似传播的功能,这将有利于整个语言,而不仅仅是这种情况。例如,我们可以强制所有参数调用为 Foo(obj[0], obj[1]),然后有一个单独的扩展运算符允许 Foo(...obj)。
    • 意识到我没有明确表示我非常尊重 anders hejlsberg,他是世界上最好的语言设计师之一。但我们可以考虑改进任何人的工作,只要有足够的后见之明,因此技术。
    【解决方案2】:

    params 参数修饰符为调用者提供了将多个参数传递给方法的快捷语法。有两种方法可以调用带有params 参数的方法:

    1) 使用参数类型的数组调用,此时params关键字无效,数组直接传递给方法:

    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 在a new post 中描述了这种行为以及它与 C# 规范的关系。

    【讨论】:

      【解决方案3】:

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

      var elements = new String[] { "1", "2", "3" };
      Foo(elements.Cast<object>().ToArray())
      

      【讨论】:

        【解决方案4】:

        你需要把它封装到另一个object[]数组中,像这样:

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

        【讨论】:

          【解决方案5】:

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

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

          用法:

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              【解决方案7】:
              new[] { (object) 0, (object) null, (object) false }
              

              【讨论】:

                猜你喜欢
                • 2018-09-09
                • 2010-10-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多