Iterator Blocks
An iterator block becomes a state machine; a disposable enumerator. Code defined in C# as this:
public static IEnumerable PublicEnumerable()
{
yield return 1;
yield return 2;
yield return 3;
}
is compiled down to the MSIL equivalent of this:
public static IEnumerable PublicEnumerable()
{
return new d__0(-2);
}
The class
[CompilerGenerated]
private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable
{
// Fields
private int <>1__state;
private int <>2__current;
// Methods
[DebuggerHidden]
public d__0(int <>1__state);
private bool MoveNext();
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator();
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator();
[DebuggerHidden]
void IEnumerator.Reset();
void IDisposable.Dispose();
// Properties
int IEnumerator.Current { [DebuggerHidden] get; }
object IEnumerator.Current { [DebuggerHidden] get; }
}
The object instance can be returned to the caller of PublicEnumerable where it will behave like the iterator block we know and love.
Anonymous Methods
Anonymous methods can access local variables defined in the same scope. When a delegate literal contains a reference to a method local variable (see: i in the following example):
public static void DelegateLiteralTest()
{
Int32 i = 5;
Action add = delegate(Int32 value) { i += value; };
Console.WriteLine(i);
add(1);
Console.WriteLine(i);
add(2);
Console.WriteLine(i);
}
the C# compiler generates a new type (closure) that resembles the following:
[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public int i;
// Methods
public <>c__DisplayClass1();
public void b__0(int value);
}
Notice how the local variable is now scoped to the instance of the closure, and how it's an instance of this closure that's used inside the method:
public static void DelegateLiteralTest()
{
<>c__DisplayClass1 __closure = new <>c__DisplayClass1();
__closure.i = 5;
Console.WriteLine(__closure.i);
__cloure.b__0(1);
Console.WriteLine(__closure.i);
__closure.b__0(2);
Console.WriteLine(__closure.i);
}
I think this is pretty darn cool.
No comments:
Post a Comment