I have a method that returns an IEnumerable<T>
. I call this method form two places, and in one of those places I do not do anything with the results.
It looks like the C# compiler removes the call to that method even if I decorate it with [MethodImpl(MethodImplOptions.NoOptimization)]
. The code doesn't even enter the calling method. If I add .ToList()
at the end, though, it is executed.
Is there a way to disable this optimization by the compiler/runtime? Looking at the ILDASM output, it looks like it's more of a runtime optimization because the call is there.
It looks like the C# compiler removes the call to that method
No, it doesn't - this is just how iterator blocks work. The code inside the iterator block will only start being executed when MoveNext()
is called for the first time. If you want to make sure that the whole method gets executed, you could just use:
SomeIteratorMethod().Count();
That will iterate over the whole sequence, throwing away results as it goes (as opposed to a call to ToList
for example, which will
If you only want to get as far as the first yield
statement, you can use
SomeIteratorMethod().Any();
If you want some code to always execute (e.g. parameter validation) but then the rest should be lazy, you need to split the method in two methods:
public IEnumerable<Foo> SomeIteratorMethod(string mustNotBeNull)
{
if (mustNotBeNull == null)
{
throw ...
}
return SomeIteratorMethodImpl(mustNotBeNull);
}
private IEnumerable<Foo> SomeIteratorMethodImpl(string mustNotBeNull)
{
... yield new Foo()...
}
Or you could just stop using an iterator block, of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With