匿名メソッド&Generics
ちょっとサンプルを作ってみた.品のないサンプルで,ごめんなさい.本当はクイックソートにしたかったんです.
namespace ClosureExample { public class ArraySorter<T> { public delegate int Compare(T t1, T t2); public void BubbleSort(T[] ts, Compare cmp) { for (int i = 0; i < ts.Length-1; i++) { for (int j =i+1; j < ts.Length; j++) { if (cmp(ts[i], ts[j]) < 0) { T tmp; tmp = ts[i]; ts[i] = ts[j]; ts[j] = tmp; } } } } } public class ArrayPrinter<T> { public delegate void Printer(T t1); public void Print(T[] ts, Printer p) { for (int i = 0; i < ts.Length; i++) { p(ts[i]); Console.Write(" "); } Console.WriteLine(""); } } class Program { static void Main(string[] args) { int[] int_array = { 1, 5, 4, 23, 7, 4, 43, 7, 1 }; ArrayPrinter<int> int_printer = new ArrayPrinter<int>(); ArraySorter<int> int_sorter = new ArraySorter<int>(); int_printer.Print(int_array, delegate (int i) { Console.Write(i); }); int_sorter.BubbleSort(int_array, delegate(int x, int y) { return x - y; }); int_printer.Print(int_array, Console.Write); string[] str_array = { "john", "alice", "bob", "johan", "mayer", "graham" }; ArrayPrinter<string> str_printer = new ArrayPrinter<string>(); ArraySorter<string> str_sorter = new ArraySorter<string>(); str_printer.Print(str_array, delegate(string s) { Console.Write(s); }); str_sorter.BubbleSort(str_array, delegate(string x, string y) { return -String.Compare(x, y); }); str_printer.Print(str_array, Console.Write); Console.ReadLine(); } } }
intとstringの配列を作って,Bubbleソートで並び替えている.ソーティングに用いる比較関数を匿名メソッドとして渡している.便利.だが,Genericにするために,クラスの中でdelegateを宣言する必要があって,それが面倒くさい.そのくらい,適当に推論してくれてもいいのに・・・
さて,サンプルの中の注目は,やはり
int_printer.Print(int_array, Console.Write);
だろう.これ,だめもとでやってみたのだが,ばっちり通るのだ.Console.Writeの定義の中から,要求されているdelegateの型に合うものを自動で引っ張ってきて,そして自動的にDelegateに変換してくれる(のかな?ごめんなさい,よく知りません.).
関数がすごくファーストクラス的に扱えて,すごく感激した.C#最高!めちゃくちゃ便利じゃん,これ.やればできる子だと思ってたよ!ArrayPrinterなんかもmapとか適当に作って,アレすれば,もっとスマートに書けるだろう.
これでGenericsがもうちょっと強力になれば,C/C++系でぶっちぎりで最強な感じの言語になるのになあ・・・ほんと,これがWindowsMEと同じ会社が作ってるとは信じられない.