Params IEnumable < T > c #

为什么不能在参数中使用 IEnumable?这能修好吗?我真的希望他们能重写旧的库,使用泛型..。

25205 次浏览

Params 参数作为数组发送,而 IEnumerable<T>不提供作为数组所需的随机访问。

在调用该方法时,必须从 IEnumable 创建数组:

TheMethod(theIEnumerable.ToArray());

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

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);

为什么不能在参数中使用 IEnumable?

这个问题的前提是设计团队必须提供一个为 没有添加语言特性的理由。这个假设是错误的。

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

“参数可枚举”特性已经被考虑和设计。它从来没有被指定,实现,测试,记录或发布。

因此,不能使用该特性。


更新: 在撰写本文时——2015年初——已经指定了,但是在2014年下半年,C # 6.0的实现、测试、文档和发布都被削减了。请看路西安的声明: 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})一样,就像对参数数组一样。这个特性的要点是,通常情况下,该方法从不使用对数组的随机访问,因此,我们可以削弱参数是一个数组的要求。Params 可能只是一个序列。

你今天就可以做到这一点:

void Frob(params int[] x) { Frob((IEnumerable<int>)x); }


void Frob(IEnumerable<int> x)
{
foreach(int y in x) ...
}

这有点痛苦。我们可以简单地允许您使用 IEnumable 作为 params 参数的类型并使用它。

这能修好吗?

希望如此。这个特性已经在列表中很长时间了。它将使许多函数在 LINQ 中工作得更好。

Frob(from c in customers select c.Age);

而不用写两个不同版本的 Frob。

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

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

意见记下了。