今回で、変換演算子は終わりです。
最後の変換演算子は、「AsEnumerable」メソッドです。
AsEnumerableメソッドは、以下の書式となっています。
public static IEnumerable<TSource> AsEnumerable<TSource>( this IEnumerable<TSource> source )
書式を見たら分かると思いますが、このメソッドはTSource型のシーケンスからTSource型の
シーケンスを返してくれます。
つまり、
IEnumerable<string> strings = new List<string>(); IEnumerable<string> strings2 = strings.AsEnumerable();
という動作をしてくれます。
なんのためにあるねんこれは!って感じなんですが、前回記述しました
拡張メソッド解決を行っている場合に役に立ちます。
拡張メソッド解決を行っている場合、元のクエリ演算子ではなく
自前で定義した拡張メソッド側が呼ばれます。
本来、これでいいのですが、時と場合によっては元の拡張メソッド
(つまり、IEnumerable
そのような場合に、AsEnumerable
IEnumerable
尚、当然ながらAsEnumerableメソッドで取得した変換後シーケンスは
元データのスナップショットではありません。なので、実行する度に評価されます。
(OfTypeメソッドやCastメソッドと同じ)
以下、サンプルです。
#region LinqSamples-18 AND LinqSamples-19 AND 拡張メソッド解決 public class LinqSamples18 : IExecutable { public void Execute() { Persons persons = new Persons { new Person { Id = 1, Name = "gsf_zero1" } ,new Person { Id = 2, Name = "gsf_zero2" } ,new Person { Id = 3, Name = "gsf_zero3" } }; // // PersonExtensionが定義されているので // そのまま実行すると、Whereの部分にてPersonExtension.Whereが // 呼ばれる. // Console.WriteLine("===== 拡張メソッドを定義した状態でそのままクエリ実行 ====="); var query = from aPerson in persons where aPerson.Id == 2 select aPerson; foreach (var aPerson in query) { Console.WriteLine(aPerson); } // // AsEnumerableメソッドを利用して、PersonsをIEnumerable<Person>に // 変換すると、カスタムWhere拡張メソッドは呼ばれない。 // Console.WriteLine("===== AsEnumerableメソッドを利用してから、クエリ実行 ====="); var query2 = from aPerson in persons.AsEnumerable() where aPerson.Id == 2 select aPerson; foreach (var aPerson in query2) { Console.WriteLine(aPerson); } } } public class Person { public int Id { get; set; } public string Name { get; set; } } public class Persons : List<Person> { } public static class PersonExtension { public static Persons Where(this Persons self, Func<Person, bool> predicate) { var result = new Persons(); Console.WriteLine("========= WHERE ========"); foreach (var aPerson in self) { if (predicate(aPerson)) { result.Add(aPerson); } } return result; } } #endregion
結果は以下のようになります。
===== 拡張メソッドを定義した状態でそのままクエリ実行 ===== ========= WHERE ======== Gsf.Samples.Person ===== AsEnumerableメソッドを利用してから、クエリ実行 ===== Gsf.Samples.Person