I mentioned that there was an exception to the general statement that the conversion of an iterator into traditional C# code is something you could have done yourself. That’s true, and it was also a pun, because the exception is exception handling.
If you have a try … finally block in your iterator,
the language executes the finally block under the following
conditions:
- After the last statement of the
tryblock is executed. (No surprise here.) - When an exception propagates out of the
tryblock. (No surprise here either.) - When execution leaves the
tryblock viayield break. - When the iterator is
Disposed and the iterator body was trapped inside atryblock at the time.
That last case can occur if somebody decides to abandon the enumerator before it is finished.
IEnumerable<int> CountTo10()
{
try {
for (int i = 1; i <= 10; i++) {
yield return i;
}
} finally {
System.Console.WriteLine(“finally”);
}
}
foreach (int i in CountTo10()) {
System.Console.WriteLine(i);
if (i == 5) break;
}
This code fragment prints “1 2 3 4 5 finally”.
If you think about it, this behavior is completely natural.
You want the finally block to execute when
the try block is finished executing, either by normal
or abnormal means.
Although control leaves the try block
during the yield return, it comes back when
the caller asks for the next item from the enumerator, so execution
of the try block isn’t finished yet.
The try is finished executing after the last statement
completes,
an exception is thrown past it,
or execution is abandoned when the enumerator is prematurely destroyed.
And this is exactly what you want when you use the finally
block to clean up resources used by the try block.
Now, technically, you can write this yourself without
using iterators, but it’s pretty ugly.
You’ll need more internal state variables to keep track of whether
the try block is still active and whether the exit
of the try block is temporary (due to yield return)
or permanent.
It’s a real pain in the neck, however, so you probably are better off
letting the compiler do the work for you.
0 comments