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

我有一个方法,它接受 params 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[]

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

132331 次浏览

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

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

一种选择是将其包装到另一个数组中:

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

有点难看,但是因为每个条目都是一个数组,所以你不能仅仅通过强制转换来解决问题... ... 比如,如果它是 Foo (params 对象条目) ,那么你可以直接这样做:

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

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

Foo((object)new object[]{ (object)"1", (object)"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,在这种情况下,编译器将为您创建包装器数组:

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 # 规范的关系。

new[] { (object) 0, (object) null, (object) false }

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

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

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

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

用法:

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