Params IEnumerable<;T>;c#

Params IEnumerable<;T>;c#,c#,generics,ienumerable,params,C#,Generics,Ienumerable,Params,为什么我不能使用带参数的IEnumerable?这个问题会解决吗?我真希望他们能重写旧库,使用泛型…参数作为数组发送,而IEnumerable不提供作为数组所需的随机访问 调用方法时,必须从IEnumerable创建数组: TheMethod(theIEnumerable.ToArray()); 啊,我想我现在可能已经明白你的意思了。我认为您希望能够声明这样的方法: public void Foo<T>(params IEnumerable<T> items) { }

为什么我不能使用带参数的IEnumerable?这个问题会解决吗?我真希望他们能重写旧库,使用泛型…

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

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

TheMethod(theIEnumerable.ToArray());
啊,我想我现在可能已经明白你的意思了。我认为您希望能够声明这样的方法:

public void Foo<T>(params IEnumerable<T> items)
{
}
IEnumerable<string> existingEnumerable = ...;
Foo(existingEnumerable);
Foo("first", "second", "third");
这就是你想要的吗?(注意,您希望第一个表单使用
T=string
,而不是带有单个元素的
T=IEnumerable

如果是这样的话,我同意这可能是有用的,但很容易做到:

public void Foo<T>(params T[] items)
{
    Foo((IEnumerable<T>) items);
}

public void Foo<T>(IEnumerable<T> items)
{
}
为什么我不能使用带参数的IEnumerable

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

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

已经考虑并设计了“params enumerable”功能。它从未被指定、实施、测试、记录或装运

因此,您不能使用该功能


更新:截至本文撰写之时——2015年初——已经明确,但C#6.0的实施、测试、文档和发布在2014年下半年被削减。请参见此处的Lucian公告:

由于它尚未实现、测试、记录和发布,因此仍然没有此类功能。希望这将使它成为C#的一个假设的未来版本


更新:我应该澄清我所说的“特征”是什么意思,因为我们都可能对“特征”有不同的想法。我说的功能是允许你说

void Frob(params IEnumerable<int> x)
{
    foreach(int y in x) ...
}
不用写两个不同版本的Frob

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

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



注意到评论。

这是一个咆哮还是一个问题?@dtb显然,两者都是+问题1。希望我也能给它一个第二个+1的咆哮。@Brainslaugs83在编辑之前,这个问题看起来像咆哮,但就问题的标题而言,这是一个非常好的问题..回到原来的问题,主要是因为埃里克·利佩特(Eric Lippert)——当时是一名C#编译器开发人员——的下面的答案引用了原来的措辞。如果他不反对措辞,我们也可能不必反对!稍微吹毛求疵,
params数组
仍然是泛型的,使其
IEnumerable
不会增加其泛型。也许你的意思是让它更通用。实现这个特性基本上意味着对ToArray的一个隐式调用,对吧?为什么被调用方一定需要它?我曾经写过的绝大多数采用params数组的方法只是将其塞进foreach中。我认为这不仅仅是一个方便的特性,因为当涉及泛型时,您的变通方法就被破坏了。很高兴知道它至少在雷达上。在我看来,params特性应该首先使用IEnumerable(虽然我知道当时它不是一个选项)。对于一些看起来很琐碎的东西来说,这是一件非常痛苦的事情。修复将大大简化API。。。请为C#5修好。求你了?我今天又一次如愿以偿了!(这一点,加上缺乏一种简单/干净的方法来创建一个单一的可枚举项,使得C#感觉像是一种“古老”的语言,它已经把linq固定住了……)如果方法编写者希望将参数设置为IEnumerable,那么为什么不能将参数设置为IEnumerable?@Ian Ringrose:一个原因是将
params
添加到语言中时,
IEnumerable
接口不存在。后来为什么没有添加它可能是因为它不是一个很有用的功能。您可以添加一个重载来支持
params T[]
IEnumerable
。为什么要进行向下投票?如果你不解释你认为错误的地方,它就不能改进答案。@Guffa不,你不能重载它——当你试图调用它时,编译器会感到困惑,并让你编写一堆额外的语法。-我们不妨添加
.ToArray()
——这很愚蠢。你确定你已经尝试过了吗?当我这样做时,它首先匹配params表单,即它匹配
public void Foo(params IEnumerable[])
Ok再次测试它,并找到错误的地方。您必须准确地提供类型
IEnumerable
而不是
List
,或者编译器更喜欢
params
版本。请参阅以获取可执行文件example@bradgonesurfing:啊,我明白你的意思了。那是因为它是通用的。如果显式调用
Foo
,则它在两种情况下都有效。我将编辑我的答案以澄清这一点。必须指定泛型类型参数是将参数作为IEnumerable添加到语言中的一个很好的原因。@SørenBoisen:同意。如果您没有指定泛型类型参数,编译器会很高兴地接受它,并且只有在运行它时才会失败(希望是在单元测试中,而不是在生产中…)。
void Frob(params IEnumerable<int> x)
{
    foreach(int y in x) ...
}
void Frob(params int[] x) { Frob((IEnumerable<int>)x); }

void Frob(IEnumerable<int> x)
{
    foreach(int y in x) ...
}
Frob(from c in customers select c.Age);