Enumerables are deferred executions. This can be problematic when used with Disposables as the latter are tend to be disposed prematurely. The below example shows the difference. ildasm shows that the compiler generates a class that implements IEnumerable<int> for Foo2 behind the scene, and returns an instance of it for Foo2. Because of that, the using is embedded into that instance so the constructing and disposal of Disposable is carried on by the deferred executed implementation. On the contrary, Foo just returns the source enumerable as a pass through, at the time it's executed, the disposal already happened. This causes the problem that if the returned enumerable depends on the disposable, at the time the enumerable is extracted from, the disposable is in the disposed state.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
static void Main(string[] args)
{
int[] source = new[] { 1, 2, 3 };
Console.WriteLine("Using Foo...");

// Outputs:
// Disposed
// 1
// 2
// 3
foreach (var item in Foo(source))
Console.WriteLine(item);

Console.WriteLine("Using Foo2...");

// Outputs:
// 1
// 2
// 3
// Disposed
foreach (var item in Foo2(source))
Console.WriteLine(item);
}

static IEnumerable<int> Foo(IEnumerable<int> source)
{
using (var disposable = new Disposable())
return source;
}

static IEnumerable<int> Foo2(IEnumerable<int> source)
{
using (var disposable = new Disposable())
foreach (var item in source)
yield return item;
}

class Disposable : IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposed");
}
}