因此,很多时候我们有一个接受IEnumerable或ICollection作为参数的函数。如果我们有单个项目,但没有集合来保存它们,我们必须在将它们传递给函数之前创建一个集合,如:
T o1, o2, o3;
Foo(new T[] { o1, o2, o3 });
我总是创建一个数组或列表,就像我在上一个例子中所做的那样。但我想知道,是否有更优雅的方式来创建所需的IEnumerable或ICollection?
如果能做到这一点,那将是非常酷的:
Foo({ o1, o2, o3 });
编译器会创建最抽象的可能集合,以满足IEnumerable或ICollection的需求(取决于函数接受哪一个)。
无论如何,如何将o1,o2和o3传递给IEnumerable或ICollection参数?
答案 0 :(得分:11)
当前版本的C#(3)支持没有显式类型的表示法,即
Foo(new [] { o1, o2, o3 })
创建一个数组。 Linq的Enumerable.Range
也可以创建连续的数字范围。其他一切都必须实施。本着Java的精神:
public static IEnumerable<T> AsList<T>(params T[] values) {
return values;
}
这样称呼:
Foo(Enumerable.AsList(o1, o2, o3));
答案 1 :(得分:3)
有时我使用了一个带有“params”参数的方法。
Foo(params T[] ts)
如果我已经死在IEnumerable上,我只需要将该方法委托给想要IEnumerable的那个。
Foo(params T[] ts) { Foo(ts.AsEnumerable()); }
你必须打电话给AsEnumerable,否则你将要进行递归。
答案 2 :(得分:2)
假设Foo期望IEnumerable&lt; T&gt;,您可以利用类型推断并执行:
T o1, o2, o3;
Foo(new []{o1, o2, o3});
答案 3 :(得分:2)
在当前版本的C#中创建一个数组并传递它可能是最简单/最优雅的方法。你可以利用隐式数组类型(即new[] { ... }
,但这是最直接的。
我怀疑你真的在寻找这种F#语法的C#等价物:
let foo = seq [ o1; o2; o3 ]
生成IEnumerable<T>
,它将迭代指定的元素。 ('Seq'实际上是'IEnumerable`的F#别名,尽管F#内置了对它们的支持。)
不幸的是,由于这是一个功能很强的概念,因此没有C#等价物 - 尽管谁知道它何时会被添加,因为C#变得越来越实用。
答案 4 :(得分:0)
如果您有一个将数组作为最后一个参数的方法,那么标记该参数params
可能是有意义的。这使您可以像这样调用方法:
Foo(o1, o2, o3);
我在为Foo()
编写单元测试时发现这特别有用,因为通常在单元测试中,我的参数是这样的,而不是在数组中。
如果Foo()
的重载没有在该位置使用数组,我建议不要这样做,因为它可能会很快混淆。
我确实希望C#语言允许params
使用IList<T>
:
void Foo(params IList<T> ts) { ... }