Tamas Tamas - 2 months ago 14
C# Question

Returning IEnumerable<T> with yield from IDisposable instance

I have found an interesting thing. c#,.NET 4.0.
I have a class what represents the IDisposable interface. In the mentioned class I have a function, what returns with IEnumerable with yield return.
At call, the controll jumps over that function. Do not step in.
Example:

class Program
{
static void Main(string[] args)
{
using (DispClass d = new DispClass())
{
d.Get2();
d.Get1();
}
}

}

public class DispClass: IDisposable
{
public DispClass()
{
Console.WriteLine("Constructor");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
public int Get1()
{
Console.WriteLine("Getting one");
return 1;
}
public IEnumerable<int> Get2()
{
Console.WriteLine("Getting 1");
yield return 1;
Console.WriteLine("Getting 2");
yield return 2;
}

}


The output:
"Constructor"
"Getting one"
"Dispose"

Where are the "Getting 1", "Getting 2"?
Without yield return with returning a local list I can see these...

Please explain!

Answer

This is expected behavior and by design. When you use yield, what's actually happening is that the Get2 method is returning an instance of a type that is automatically implemented by the compiler. That types implements IEnumerable<T> interface. The code inside your iterator method doesn't actually get called until the enumerable object is enumerated. Since you aren't enumerating over the result of the Get2 call, your code is never being called. To force it, use something like ToArray() or ToList():

 d.Get2().ToList();