2010-02-04 79 views
3

如果我有一个函数传递数组变量长度参数列表

void Foo(params int[] bar){} 

下运行良好:

int[] a1 = {1, 2, 3}; 
int[] a2 = {4, 5, 6}; 
Foo(1, 2, 3); 
Foo(a1); 

但这些给编译错误:

Foo(a1, 1, 2, 3); 
Foo(1, 2, a1); 
Foo(1, a1, 2); 
Foo(a1, a2, 1, 2, 3); 

,因为只有第一个参数被允许是一个int [],其余的必须是整数。

最后一个例子是我想要做的,但语言不会让我没有先组合数组。我非常喜欢这种语法的简单性,而且我宁愿不添加更多的代码。有没有人有一个很好的方式来做到这一点?

+4

是什么让你觉得'美孚(A1,1,2,3);''那里是a1'一个'INT []'应该工作?你测试过了吗?在哪个版本的编译器上? – 2010-02-04 17:06:36

+0

你确定'Foo(a1,1,2,3)'有效,它调用与'Foo(1,2,3)'相同的过载?我在.net 3.5 SP1上进行了测试,但对我无效。 – 2010-02-04 17:09:52

+1

够公平的。视觉工作室让我没有警告地打字,但没有其他人。它们都无法编译。我会编辑。 – captncraig 2010-02-04 17:13:26

回答

11

这很奇怪。 Foo(a1, 2, 3)应该不起作用。你应该传递一个数组或一堆整数。你不能把它们混在一起。你有另外一个过载或者什么吗?

这样做并没有真正的语法。最简洁的一个我能想到的是:

Foo(a1.Concat(a2).Concat(new[] {1,2,3}).ToArray()); 
+0

我同意'Foo(a1,2,3)'不能没有另一个超负荷工作。 – leppie 2010-02-04 17:06:36

2

同意,它很奇怪Foo(a1, 2, 3)作品。

继承人.Concat的扩展方法使Mehrdad的语法在眼睛上更容易一些。

public T[] Concat<T>(this T[] first, params T[] other) 
    { 
     T[] output = new T[first.Length+other.Length]; 

     first.CopyTo(output,0); 
     other.CopyTo(output,first.Length); 
     return output; 
    } 

可以如下使用:

Foo(a1.Concat(a2).Concat(1,2,3)); 
+1

请注意,'Enumerable.Concat'是延迟评估,而你的每次调用都会做副本。如果Concat调用的数量增加,它可能效率低下。 – 2010-02-04 17:25:11

+0

非常好的一点。 – 2010-02-04 17:31:25