71

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

4

3 回答 3

110

为什么我不能使用带参数的 IEnumerable?

这个问题的前提是设计团队必须提供一个向语言添加功能的理由。这个假设是错误的。

相反,为了让你使用一个特性,它需要被考虑、设计、指定、实现、测试、记录和发布。所有这些都有很大的成本。

“params enumerable”特性已经被考虑和设计。它从未被指定、实施、测试、记录或交付。

因此,您不能使用该功能。


更新:在撰写本文时 - 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 数组所做的一样。该功能的要点是,该方法通常从不使用对数组的随机访问,因此,我们可以削弱参数是数组的要求。参数可能只是一个序列。

您今天可以通过重载来做到这一点:

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。

然而,它只是一个“小便利”的功能;它实际上并没有为语言增加很多新的力量。这就是为什么它从来没有在优先级列表中达到足够高的位置以使其进入“编写规范”阶段。

我真的希望他们重写旧库以使用泛型。

评论指出。

于 2010-01-24T21:06:59.763 回答
13

啊,我想我现在可能明白你的意思了。我认为您希望能够声明这样的方法:

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)
{
}

我发现我这样做的频率不足以使上述问题成为一个特别难看的解决方法。

请注意,在调用上述代码时,您需要显式指定类型参数,以避免编译器偏爱params示例。例如:

List<string> x = new List<string>();
Foo<string>(x);
于 2010-01-24T20:55:01.307 回答
5

params 参数作为数组发送,并且 anIEnumerable<T>不提供充当数组所需的随机访问。

调用该方法时,您必须从 IEnumerable 创建数组:

TheMethod(theIEnumerable.ToArray());
于 2010-01-24T20:54:49.340 回答