|
試してないですが、ソートに関してはクエリ式の方なら、配列のままでもいけるはず。
あと、はじめの頃はラムダ式がイメージできないでしょうから、簡単なサンプル。
たとえば、リストの中から、最も大きな数字を選び出すメソッド。
まずは、メソッドではなく、処理を考えます。
質問内容からして以下のコードは理解できると思います。
var NumList = new List<int>()
{
15, 28, 9, 53, 26, 37, 24, 62, 19, 54
};
int MaxNum = -1;
foreach (var Num in NumList)
{
if (Num > MaxNum) MaxNum = Num;
}
Trace.WriteLine(string.Format("最大の数字は{0}です", MaxNum));
この最大値を求める処理をメソッド化します。
Listクラスの派生クラスを作って、MyList.Max()を実装します。
※ List.Max()ってのがすでにいるので無意味なんですが、あくまでサンプルって
ことで(^^;
public class MyList : List<int>
{
int Max()
{
int MaxNum = this[0];
foreach (var Num in this)
{
if (Num > MaxNum) MaxNum = Num;
}
return MaxNum;
}
}
実行するときは以下のような感じです。
var NumList = new MyList()
{
15, 28, 9, 53, 26, 37, 24, 62, 19, 54
};
Trace.WriteLine(string.Format("最大の数字は{0}です", NumList.Max()));
問題ないですね。
同様に、最小値を求める処理を実装すると以下のような感じです。
public class MyList : List<int>
{
int Min()
{
int MinNum = this[0];
foreach (var Num in this)
{
if (Num < MinNum) MinNum = Num;
}
return MinNum;
}
}
違いはif()の中の条件式だけでしょ。こういうのを共通化するのをやってみます。
if()の処理だけ関数化します。
public class MyList : List<int>
{
int Find()
{
int FindNum = this[0];
foreach (var Num in this)
{
FindNum = FindMethod(FindNum, Num);
}
return FindNum;
}
int FindMethod(int X, int Y) { return (X > Y) ? X : Y; }
}
そして、FindMethod()をdelegate化します。
public delegate int FindDelegate (int X, int Y);
public class MyList : List<int>
{
public int Find(FindDelegate Find)
{
int FindNum = this[0];
foreach (var Num in this)
{
FindNum = Find(FindNum, Num);
}
return FindNum;
}
}
delegate化したので、関数は外部から与えます。
int MaxFind(int X, int Y) { return (X > Y) ? X : Y; }
これで、最大値を求めるなら以下のように呼べます。
Trace.WriteLine(string.Format("最大の数字は{0}です", NumList.Find(MaxFind)));
同様に最小値を求めるなら以下のような感じです。
Trace.WriteLine(string.Format("最小の数字は{0}です", NumList.Find(MinFind)));
分かりますか、NumList.Find()に渡す関数を差し替えるだけで動作が変わるでしょ。
でも、差し替える関数 MaxFind(), MinFind() はものすごく簡単な処理しかしてない。
だから、いちいち関数書くのも面倒。
そこで出てくるのがラムダ式です。
Trace.WriteLine(string.Format("最大の数字は{0}です",
NumList.Find((X, Y) => (X > Y) ? X : Y))
);
このように書くと、関数を定義して、NumList.Find()に渡したことになるわけです。
int MaxFind(int X, int Y) { return (X > Y) ? X : Y; }
を
(X, Y) => (X > Y) ? X : Y
とすると同じ意味になるわけです。
長く説明しましたが、
ソート処理も、内部処理的にはデータ型が何であっても大して処理に違いが無いわけです。
唯一違うのがデータ型によって、ある要素とある要素の大小比較処理が違うだけです。
だから、ある要素とある要素の大小比較処理だけを外出し関数としてdelegate化してあるわ
けです。
public void List<T>.Sort(Comparison<T> comparison)
このComparisonに渡す関数をラムダ式で書いてやればそれでいい。
ラムダ式について詳しくは解説書を読んでください。
|