为什么我不能使用带有参数的IEnumerable?这会被解决吗?我真的希望他们能重写旧库以使用泛型......
答案 0 :(得分:90)
为什么我不能使用带有参数的IEnumerable?
问题预先假设设计团队必须提供不为该语言添加功能的理由。这个预设是错误的。
相反,为了让您使用某个功能,需要对其进行思考,设计,指定,实施,测试,记录和发送。所有这些都有很高的成本。
“params可枚举”功能已被考虑和设计。它从未被指定,实施,测试,记录或发货。
因此,您无法使用此功能。
更新:在撰写本文时 - 2015年初 - 现已确定,但2014年下半年C#6.0的实施,测试,文档和运输已被删除。请参阅Lucian在此处的公告:http://roslyn.codeplex.com/discussions/568820
由于尚未实施,测试,记录和发货,因此仍然没有此类功能。希望这将使它成为C#的假设未来版本。
更新:我应该澄清“特征”的意思,因为我们的头脑中可能有不同的想法是什么“特征”。我正在谈论的功能是允许你说出像
这样的内容void Frob(params IEnumerable<int> x)
{
foreach(int y in x) ...
}
然后呼叫站点可以是传递整数序列的“正常形式”,或者是Frob的“扩展形式”(10,20,30)。如果在扩展形式中,编译器生成调用,就像你说Frob(new int [] {10,20,30})一样,就像它对param数组一样。该特征的关键在于,通常情况下该方法从不使用对数组的随机访问,因此,我们可以削弱params为数组的要求。 params可能只是一个序列。
今天你可以通过重载来做到这一点:
void Frob(params int[] x) { Frob((IEnumerable<int>)x); }
void Frob(IEnumerable<int> x)
{
foreach(int y in x) ...
}
这有点痛苦。我们可以简单地允许你使用IEnumerable作为params参数的类型并完成它。
这会被解决吗?
我希望如此。此功能已列入名单很长一段时间。它可以使很多函数在LINQ上运行得更好。
Frob(from c in customers select c.Age);
无需编写两个不同版本的Frob。
但是,它只是一个“小便利”功能;它实际上并没有为语言添加大量新功能。这就是为什么它从未在优先级列表上做得足够高,以使其达到“规范写入”阶段。
我真的希望他们重写旧库以使用泛型。
评论指出。
答案 1 :(得分:12)
啊,我想我可能现在明白了你的意思。我想你希望能够声明一个像这样的方法:
public void Foo<T>(params IEnumerable<T> items)
{
}
然后能够用这样的“正常”参数调用它:
IEnumerable<string> existingEnumerable = ...;
Foo(existingEnumerable);
或有多个这样的参数:
Foo("first", "second", "third");
这就是你要追求的吗? (注意到您希望第一个表单使用T=string
,而不是T=IEnumerable<string>
使用单个元素...)
如果是这样,我同意可以有用 - 但它很容易实现:
public void Foo<T>(params T[] items)
{
Foo((IEnumerable<T>) items);
}
public void Foo<T>(IEnumerable<T> items)
{
}
我发现我经常这样做不足以使上述变得特别难看。
请注意,在调用上面的代码时,您需要显式指定type参数,以避免编译器更喜欢params
示例。例如:
List<string> x = new List<string>();
Foo<string>(x);
答案 2 :(得分:4)
params参数作为数组发送,IEnumerable<T>
不提供充当数组所需的随机访问。
调用方法时,必须从IEnumerable创建数组:
TheMethod(theIEnumerable.ToArray());