2008-08-30 30 views
104

我已经这需要一个方法params对象[]如:如何单个对象[]传递给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数组?

回答

82

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

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

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

+0

params的工作方式似乎是不必要的,而次优的c#设计,因为我们已经习惯了其他语言。 params本来可以用来接受一种形式,并且可以增加一些可以使整个语言受益的扩展类功能,而不仅仅是这种情况。例如,我们可以强制所有参数调用都是Foo(obj [0],obj [1]),然后有一个允许Foo(... obj)的单独传播运算符。 – Lee 2017-12-15 19:21:39

3

你需要将其封装到另一个对象[]数组,像这样:

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

一种选择是,你可以把它包装成另一个数组:

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

类的丑陋,但由于每个项目是一个数组,你不能只是施加它使问题消失...如果它是Foo(params object items),那么你可以这样做:

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

或者,你可以尝试定义富的另一重载实例,它只需在单个阵列:

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

参数修饰符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); 

编辑:雷蒙德陈描述了这种行为,以及它如何涉及a new post的C#规范。

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

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

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