それ,名前のあるメソッドで書けないよ
『Boost.Bind を C# で作りたい(2) - melt日記』より.
とりあえず全部の引数を束縛するのであれば簡単に作れるようだ。
delegate R Function<R>(); delegate R Function<R, T1>(T1 t1); delegate R Function<R, T1, T2>(T1 t1, T2 t2); // 以下略 Function<R> Bind<R>(Function<R> f) { return delegate { return f(); }; } Function<R> Bind<R, T1>(Function<R, T1> f, T1 t1) { return delegate { return f(t1); }; } Function<R> Bind<R, T1, T2>(Function<R, T1> f, T1 t1, T2 t2) { return delegate { return f(t1, t2); }; } // 以下略でもこれだと、
int func(int n) { return 0; } Function<int> f = Bind(func, 100);と書くと
'Bind<R,T1>(Function<R,T1>, T1)' に対する型引数を使い方から推論することはできません。型引数を明示的に指定してください。って出る。ダメポ。
Method group conversions と Generic Method の型推論の順序の兼ね合いで,これエラーになっちゃうんですな.C# 3.0 でも同じエラー.
でも C# 3.0 のラムダ式や C# 3.0 の Anonymous Delegate だと OK.不思議?*1
using System; using System.Collections.Generic; delegate R Function<R>(); delegate R Function<R, T1>(T1 t1); static class Program { static Function<R> Bind<R, T1>(Function<R, T1> f, T1 t1) { return delegate { return f(t1); }; } static int func(int n) { return 0; } static void Main(string[] args) { // compile error (C# 2.0, C# 3.0) / OK (C# 4.0) Function<int> f1 = Bind(func, 100); // OK (C# 3.0, C# 4.0) Function<int> f2 = Bind(n => 0, 100); // compile error (C# 2.0) / OK (C# 3.0, C# 4.0) Function<int> f3 = Bind(delegate(int n) { return 0; }, 100); } }
f3 の振る舞いはちょっと印象的.C# 2.0 だとエラーになるけど C# 3.0 だとエラーにならない.びっくり?
参考資料
- http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx:title=
- 「なんで Method Groups の戻り値の推論ができんのじゃー」に関する回答.やっちゃうと,特定の Generics Method を含む Method Groups の型推論でループが発生してしまう,と.
追記
- 2008年5月23日
- 2008年11月11日
- Visual Studio 2010 CTP にて,最初のコードがコンパイルできるようになっていることを確認.
*1:理由は参考資料参照のこと