突然思いついた技です。
非常にシンプルなので、既に誰かが考えて実践していると思いますが、一応メモっておきましょう。
問題提起 §
匿名メソッドを使う場合には、それに対応するデリゲート型を宣言しなければなりません。
MethodInvokerで済めば良いのですが、それを含むアセンブリを参照していない場合や、引数や戻り値が違う場合は使えません。
その場でサクッと書けるのが匿名メソッドの良いところなのに、その場限りの匿名メソッドのためにデリゲート型を宣言するのはめんどくさいな~ (横着者)。
ジェネリック デリゲートを使おう §
デリゲートはジェネリックにも適用できます。
ということは、引数の違いのバリエーションさえ揃えておけば、変数や引数を宣言するその場で型を指定することもできるはずです。
というわけで書いてみました。
ジェネラル デリゲート §
delegate TR General0<TR>();
delegate TR General1<TR, T1>(T1 p1);
delegate TR General2<TR, T1, T2>(T1 p1, T2 p2);
delegate TR General3<TR, T1, T2, T3>(T1 p1, T2 p2, T3 p3);
delegate TR General4<TR, T1, T2, T3, T4>(T1 p1, T2 p2, T3 p3, T4 p4);
delegate void General0Nr();
delegate void General1Nr<T1>(T1 p1);
delegate void General2Nr<T1, T2>(T1 p1, T2 p2);
delegate void General3Nr<T1, T2, T3>(T1 p1, T2 p2, T3 p3);
delegate void General4Nr<T1, T2, T3, T4>(T1 p1, T2 p2, T3 p3, T4 p4);
ちなみにvoidだけは特殊であるため、戻り値がvoidのケースのみ別の定義を与えています。
NrはNo return valueの略のつもり。
使用例 §
class Program
{
static void Main(string[] args)
{
General1Nr<int> writer = delegate(int x) { Console.WriteLine(x); };
General2<int, int, int> adder = delegate(int x, int y) { return x + y; };
writer(adder(1,2));
}
}
補足 §
このようなテクニックが良いのか悪いのかは分かりません。
使う場合は自己責任で。
とりあえず、何回も出現するデリゲート型なら、明示的な名前で定義を行う方が良いと思います。