こちらのエントリーに書いたように、yield return は遅延実行されます。
LINQ の標準的な拡張メソッドは遅延実行されます。
ゆえにこれらは C# で yield return する形で実装されてるってことですね。
試しに簡単な自作拡張メソッドで試してみました。
前のエントリーから結果は明らかなんですが、一応は拡張メソッドでも書きたかったので。
(ジェネリックは使ってません、今回の趣旨とは違うので)
class Program
{
static void Main(string[] args)
{
int[] numList = { 4, 5, 1, 2, 3, 6 };
IEnumerable list1 = numList.GetEven1();
IEnumerable list2 = numList.GetEven2();
Console.WriteLine("*** 結果出力前 ***");
foreach (int i in list1)
Console.WriteLine(i);
foreach (int i in list2)
Console.WriteLine(i);
Console.ReadLine();
}
}
static class MyExtensions
{
public static IEnumerable GetEven1(this IEnumerable list)
{
Console.WriteLine("GetEven1 呼び出し");
List result = new List();
foreach (int n in list)
{
if (n % 2 == 0)
result.Add(n);
}
return result;
}
public static IEnumerable GetEven2(this IEnumerable list)
{
Console.WriteLine("GetEven2 呼び出し");
foreach (int n in list)
{
if (n % 2 == 0)
yield return n;
}
}
}
GetEven1 がリストを生成するもの、GetEven2 が yield return で要素を返すものです。
結果は確かにこうなります。

慣れないと、実行結果がなんか変に思えてしまう。引っかかるケースが出てきそう・・・。
でも、「なるほどね~、反復子ってそういうことか」ってわかった気にさせる(でも実はわかってない)、面白い例かもしれない。