c# - List<T>.ForEach 与自定义 IEnumerable<T> 扩展

标签 c# linq extension-methods

假设我有一个类:

public class MyClass
{
   ...
}

和一个返回 IEnumerable<MyClass> 的网络服务方法

网络服务的消费者定义了一些方法:

public void DoSomething(MyClass myClass)
{
   ...
}

现在,消费者可以调用DoSomething关于 webservice 方法的结果有两种方式:

var result = // web service call

foreach(var myClass in result)
{
   DoSomething(myClass);
}

或:

var result = // web service call

result.ToList().ForEach(DoSomething);

不用说,我更喜欢第二种方式,因为它更短且更具表现力(一旦你习惯了我的语法)。

现在,网络服务方法只公开了一个 IEnumerable<MyClass> , 但它实际上返回一个 List<MyClass>其中(AFAIK)意味着实际的序列化对象仍然是 List<T> .但是,我发现(使用反射器)Linq 方法 ToList()复制 IEnumerable<T> 中的所有对象不管实际的运行时类型如何(在我看来,它可以将参数转换为 List<T> 如果它已经是一个)。

这显然有一些性能开销,特别是对于大列表(或大对象列表)。

那么我能做些什么来克服这个问题,为什么没有ForEach Linq 中的方法?

顺便说一句,他的问题隐约与this one有关.

最佳答案

你可以写一个扩展方法但是有good reasons为什么 ForEach 没有在 IEnumerable<T> 上实现.第二个例子

result.ToList().ForEach(DoSomething);

将 IEnumerable 复制到一个列表中(除非它已经是一个列表,我假设)所以你最好只用旧的 foreach(var r in result) {} 迭代 IEnumerable .

附录:

对我来说,Eric Lippert 的文章的关键点是添加 ForEach 没有任何好处并且增加了一些潜在的陷阱:

The second reason is that doing so adds zero new representational power to the language. Doing this lets you rewrite this perfectly clear code:

foreach(Foo foo in foos){ statement involving foo; }

into this code:

foos.ForEach((Foo foo)=>{ statement involving foo; });

which uses almost exactly the same characters in slightly different order. And yet the second version is harder to understand, harder to debug, and introduces closure semantics, thereby potentially changing object lifetimes in subtle ways.

关于c# - List<T>.ForEach 与自定义 IEnumerable<T> 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2297364/

相关文章:

c# - 如何从 USB token (etoken pro 72 k(Java))读取证书并附加到 pdf

c# - 通过 Google API 为新用户注册两步验证

LINQ to SQL DAL + BLL + 演示文稿

html - 从特定网页 Div 中获取图像标签

c# - 使用泛型创建 HtmlHelper 扩展方法

c# - 为什么我不能 "see"这个枚举扩展方法?

c# - NInject 不解决特定的依赖关系

C# 统一错误 : Could not load file or assembly

c# - Entity Framework - 在一个查询中获取 'fake' 导航属性

arrays - 在 Swift 3 中扩展类型化数组(基本类型如 Bool)?