我有一个方法,它接受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数组?
答案 0 :(得分:94)
简单的类型转换将确保编译器在这种情况下知道您的意思。
Foo((object)new object[]{ (object)"1", (object)"2" }));
由于数组是对象的子类型,所以这一切都有效。虽然有点奇怪的解决方案,但我同意。
答案 1 :(得分:69)
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)或者,如Adam所述,将参数强制转换为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在a new post中描述了此行为及其与C#规范的关系。
答案 2 :(得分:8)
这是涉及LINQ的单行解决方案。
var elements = new String[] { "1", "2", "3" };
Foo(elements.Cast<object>().ToArray())
答案 3 :(得分:3)
您需要将其封装到另一个object []数组中,如下所示:
Foo(new Object[] { new object[]{ (object)"1", (object)"2" }});
答案 4 :(得分:1)
一个选项是你可以将它包装到另一个数组中:
Foo(new object[]{ new object[]{ (object)"1", (object)"2" } });
有点难看,但由于每个项目都是一个数组,你不能只是为了让问题消失而放弃......比如它是Foo(params对象项目),那么你可以这样做:< / p>
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 });
}
答案 5 :(得分:1)
new[] { (object) 0, (object) null, (object) false }
答案 6 :(得分:1)
解决这个问题的另一种方法(这不是很好的练习,但看起来很漂亮):
static class Helper
{
public static object AsSingleParam(this object[] arg)
{
return (object)arg;
}
}
用法:
f(new object[] { 1, 2, 3 }.AsSingleParam());