参数IEnumerable <t> c#</t>

时间:2010-01-24 20:49:52

标签: c# generics ienumerable params

为什么我不能使用带有参数的IEnumerable?这会被解决吗?我真的希望他们能重写旧库以使用泛型......

3 个答案:

答案 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());