参数IEnumerable <T> c#

Des*_*ted 60 c# generics ienumerable params

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

Eri*_*ert 96

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

问题预先假定设计团队必须提供向该语言添加功能的理由.这个预设是错误的.

相反,为了让您使用某个功能,需要对其进行思考,设计,指定,实施,测试,记录和发送.所有这些都有很高的成本.

"params可枚举"功能已被考虑和设计.它从未被指定,实施,测试,记录或发送.

因此,您无法使用该功能.


UPDATE:写这篇文章的- - 2015年年初,现在已经明确,但实施,测试,文档和航运是在2014年在这里见卢西恩宣布后期削减C#6.0 的HTTP://roslyn.codeplex. com/discussion/568820.

由于它尚未实施,测试,记录和发货,因此仍然没有这样的功能.希望这将使它成为C#的假设未来版本.


更新:我应该澄清"特征"的含义,因为在我们的头脑中我们都有不同的想法是什么"特征".我正在谈论的功能是允许你说出类似的话

void Frob(params IEnumerable<int> x)
{
    foreach(int y in x) ...
}
Run Code Online (Sandbox Code Playgroud)

然后调用位置可以是在通过整数的序列,或FROB(10,20,30)的"扩展的形式"的"正常的形式".如果在扩张形式中,所述编译器生成的呼叫,仿佛你说FROB(新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) ...
}
Run Code Online (Sandbox Code Playgroud)

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

这会被解决吗?

希望如此.此功能已列入名单很长一段时间.它可以使很多函数在LINQ上运行得更好.

Frob(from c in customers select c.Age);
Run Code Online (Sandbox Code Playgroud)

无需编写两个不同版本的Frob.

然而,它只是一个"小便利"功能; 它实际上并没有为语言添加大量新功能.这就是为什么它从未在优先级列表上做得足够高,以使其达到"规范写入"阶段.

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

评论指出.

  • 对于看似微不足道的事情来说,这背后是如此痛苦.修复将大大简化API ...请修复C#5.请? (8认同)
  • 为什么被叫者需要那个?采用我曾经写过的params数组的绝大多数方法只是把那个东西塞进了foreach. (7认同)
  • 我今天再次实现这一愿望!(这和缺少一种简单/干净的方式来创建可枚举的单个项目开始使C#感觉像是一个"旧"语言,已经使用了linq螺栓...) (5认同)
  • 实现此功能基本上意味着对ToArray的隐式调用,对吧? (3认同)
  • 我认为这不仅仅是一个便利功能,因为当涉及到通用时,你的解决方法就会被打破.很高兴知道它至少在雷达上.IMO,params功能应该首先使用IEnumerable(虽然我当时知道它不是一个选项). (3认同)

Jon*_*eet 11

嗯,我想我可能现在已经明白你的意思.我想你希望能够声明一个像这样的方法:

public void Foo<T>(params IEnumerable<T> items)
{
}
Run Code Online (Sandbox Code Playgroud)

然后能够用这样的"正常"参数调用它:

IEnumerable<string> existingEnumerable = ...;
Foo(existingEnumerable);
Run Code Online (Sandbox Code Playgroud)

或者像这样的多个参数:

Foo("first", "second", "third");
Run Code Online (Sandbox Code Playgroud)

这就是你要追求的吗?(注意到你想要使用第一个表单T=string,而不是T=IEnumerable<string>单个元素......)

如果是这样,我同意它可能有用 - 但它很容易:

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

public void Foo<T>(IEnumerable<T> items)
{
}
Run Code Online (Sandbox Code Playgroud)

我没有发现我经常这样做,以使上述特别难看的解决方法.

请注意,在调用上面的代码时,您需要显式指定type参数,以避免编译器更喜欢该params示例.例如:

List<string> x = new List<string>();
Foo<string>(x);
Run Code Online (Sandbox Code Playgroud)

  • 必须指定泛型类型参数是一个很好的理由,因为作为IEnumerable的params将是该语言的一个很好的补充. (4认同)
  • 好了再试一次,发现你错了.你必须提供类型``IEnumerable <T>``而不是``List <T>``或者编译器更喜欢``params``版本.有关可执行示例,请参阅https://gist.github.com/bradphelan/9fddca0fa5f1c07ba736 (2认同)

Guf*_*ffa 6

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

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

TheMethod(theIEnumerable.ToArray());
Run Code Online (Sandbox Code Playgroud)

  • 如果这是方法编写者想要的,为什么不能将 params 参数设置为 IEnumerable&lt;T&gt; ? (3认同)