ページ

2011年4月20日水曜日

◆拡張メソッドの定義

拡張メソッドであるWhereは以下のようなLINQなどで使える。

using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
  static void Main(string[] args)
  {
    int[] n = { 2, 3, 5, 7, 11, 13 };
    IEnumerable<int> numQuery2 = n.Where(num => num < 10);
    foreach (int i in numQuery2)
    {
      Console.WriteLine(i);
// 出力:
// 2
// 3
// 5
// 7
    }
  }
}


まぁこのサンプル自体はLINQが少しでも判っていれば簡単に書けるだろう。
ただし、Where拡張メソッドの定義は以下のようになっているのだが、この定義を見て上記Whereの構文が書けるだろうか。

public static IEnumerable<TSource> Where<TSource>(
  this IEnumerable<TSource> source,
  Func<TSource, bool> predicate
)


はっきり言ってチンプンカンプンである。
拡張メソッドのの使い勝手自体は気に入っているがその仕組みはちょっと無理やりっぽい感じもある。
そもそもあるクラスのメソッドを他のクラスを使って拡張するというのは反則ではなかろうか。(笑)

まず戻り値はIEnumerable<TSource> 型。これは判る。
次に、引数はIEnumerable<TSource>型Func<TSource, bool> 型の2つを取る。そして最初の引数にはthisなんてよく判らないキーワードが付いている。
どうも、この2つの引数は上記サンプルで使用しているWhereメソッドの引数(num => num < 10)を単純にさすわけではなさそうだ。
結果から類推するに、Whereメソッドは最初の引数
 IEnumerable<TSource> 型に対する拡張ができるよという事ではなかろうか。(逆に言うとIEnumerable<TSource> 型でWhere拡張メソッドが使えるという事)
thisというキーワードは拡張メソッドだよってしるしかな。
2つ目の引数が実際に拡張メソッドとして使った時の引数。
ここではFunc<TSource, bool>デリゲートなので、TSourceを引数としてboolを返すメソッドまたは同等のラムダ式という事で
Where(num => num < 10) という使い方ができるという事ではなかろうか。
ちなみにwhere<TSource>の<TSource>は型推定(だっけ?)で推定できるので省略可能って事。

と解釈してみた。

0 件のコメント:

コメントを投稿

私が最近チェックした記事