假设我有一个类:
public class MyClass
{
...
}
有一个Web服务方法,返回一个IEnumerable<MyClass>
Web服务的使用者定义了一些方法:
public void DoSomething(MyClass myClass)
{
...
}
现在,消费者可以通过两种方式调用webservice方法的结果上的
DoSomething
函数:var result = // web service call
foreach(var myClass in result)
{
DoSomething(myClass);
}
或者:
var result = // web service call
result.ToList().ForEach(DoSomething);
毋庸置疑,我更喜欢第二种方式,因为它更加简洁和表达(一旦你习惯了语法,我已经习惯了)。
现在,Web服务方法仅公开一个
IEnumerable<MyClass>
,但实际上返回的是一个 List<MyClass>
,这意味着实际序列化对象仍然是一个 List<T>
(据我所知)。但是,我发现(使用反射器)Linq 方法 ToList()
复制了 IEnumerable<T>
中所有对象,而不考虑实际运行时类型(在我看来,如果它已经是一个列表,则可以将参数强制转换为 List<T>
)。这显然会带来一些性能开销,特别是对于大型列表(或大型对象列表)。
那么,我该怎么解决这个问题呢?为什么 Linq 没有
ForEach
方法?顺便说一下,他的问题与 this one 稍有关联。
ToList()
方法在对象为值类型时不会创建副本。相反,它创建一个具有相同引用的列表,这样在循环仍然活动时可以修改原始列表(在某些情况下可能需要这样做)。它还允许使用变量委托,以防DoSomething
操作依赖于其他内容或是一个参数,这可能是ForEach
方法有意义的情况 - 尽管你也可以不用它。 - RedGlyph