禁用循环返回值的C#优化
作者:互联网
我有一个返回IEnumerable< T>的方法.我把这个方法称为两个地方,在其中一个地方我没有对结果做任何事情.
看起来C#编译器删除了对该方法的调用,即使我用[MethodImpl(MethodImplOptions.NoOptimization)]装饰它也是如此.代码甚至没有进入调用方法.但是,如果我在末尾添加.ToList(),它就会被执行.
有没有办法通过编译器/运行时禁用此优化?查看ILDASM输出,看起来它更像是运行时优化,因为调用就在那里.
解决方法:
It looks like the C# compiler removes the call to that method
不,它没有 – 这就是迭代器阻塞工作的方式.迭代器块中的代码只有在第一次调用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()...
}
或者你当然可以停止使用迭代器块.
标签:c,net,jit,csc 来源: https://codeday.me/bug/20190612/1224419.html