我有一个返回IEnumerable<T>
的方法。我从两个地方调用这个方法,在其中一个地方,我对结果不做任何处理。
看起来,即使我用[MethodImpl(MethodImplOptions.NoOptimization)]
修饰它,c编译器也会删除对该方法的调用。代码甚至没有输入调用方法。不过,如果我在末尾加上.ToList()
,它就会被执行。
编译器/运行时是否可以禁用此优化?看看ildasm输出,它看起来更像是一个运行时优化,因为调用已经存在。
最佳答案
看起来C编译器删除了对该方法的调用
不,它不是-这就是迭代器块的工作方式。迭代器块中的代码只在第一次调用MoveNext()
时才开始执行。如果要确保执行整个方法,可以使用:
SomeIteratorMethod().Count();
它将遍历整个序列,并在运行时丢弃结果(与调用
ToList
相反,例如如果只想得到第一个
yield
语句,可以使用SomeIteratorMethod().Any();
如果希望某些代码始终执行(例如,参数验证),但其他代码应该是惰性的,则需要将该方法拆分为两个方法:
public IEnumerable<Foo> SomeIteratorMethod(string mustNotBeNull)
{
if (mustNotBeNull == null)
{
throw ...
}
return SomeIteratorMethodImpl(mustNotBeNull);
}
private IEnumerable<Foo> SomeIteratorMethodImpl(string mustNotBeNull)
{
... yield new Foo()...
}
当然,也可以停止使用迭代器块。