Since C# 2.0 we’ve been able to declare iterator blocks inside classes and return values from them using the yield return keywords. Behind the scenes the compiler has generously converted our rather simple iterator block into its own class, a state machine which fully implements either the IEnumerable or IEnumerator interface. Using ILSpy or Reflector you can get a glimps of what these classes look like.
In C# 3.5 Extension Methods were added to the language providing a simple means of writing static methods that will appear in existing classes or interfaces’ intellisense popup.
What I am interested in doing is combining these two concepts and in doing so I’m having a difficult time. My frustration centers around the fact that in an iterator block, the this keyword refers to the class that the iterator block is in instead of the compiler generated class which holds the implementation of the iterator block.
What I’d like to do is something like this:
public static class IteratorExtensions
{
public static void DoSomething<T>(this IEnumerable<T> iterator)
{
Console.WriteLine("Running iterator block of type :" + typeof(T).Name);
}
}
public class IteratorExample
{
public IEnumerable<string> MyIterator()
{
yield return "Hello";
this.DoSomething();
yield return "World";
}
}
Unfortunately in this context this refers to an instance of IteratorExample and not to an instance of the generated MyIterator class. Is there any way to get a reference in the iterator or will I have to rethink my plans?
No clean way, no. All
thisusage is intercepted and refers to the declaring instance.You could possibly do something horrible involving abusing the stack or similar, but nothing tidy is obvious. You could maybe chain the iterators LINQ-style instead? i.e.
and use
originalIterator.WithLogging()