匿名メソッド&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と同じ会社が作ってるとは信じられない.