無名関数の型推論の例
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/09/29 09:09 UTC 版)
無名関数の型推論においては、複雑な状況が発生する。 C#の例を以下に示す。 // 複数のデリゲート型を定義delegate void TwoStringAction(string left, string right);delegate void OneParamAction(object o);delegate void TwoParamAction(object o, EventArgs e);delegate void TwoIntegerAction(int x, int y);// メソッドのオーバーロードを用意する。有効化するオーバーロードの種類により、型推論の可否が変化する。static void SomeMethod(TwoStringAction action) { /* Pattern 1 */ }//static void SomeMethod(OneParamAction action) { /* Pattern 2 */ }//static void SomeMethod(TwoParamAction action) { /* Pattern 3 */ }//static void SomeMethod(TwoIntegerAction action) { /* Pattern 4 */ }static void Main() { // メソッドのオーバーロードがPattern 1のみの場合、全ての文が有効(型推論可能)である。 SomeMethod((o, e) => { /*No-op*/ }); /* 1行目 */ SomeMethod((o, e) => { o = o + e; }); /* 2行目 */ SomeMethod((o, e) => { o = "" + o + e; }); /* 3行目 */ SomeMethod(delegate { /*No-op*/ }); /* 4行目 */} SomeMethod(OneParamAction action) の行を有効にすると、Mainメソッドの4行目の型推論が効かなくなる。4行目の匿名関数は引数リストを省略できるため、1引数、2引数のどちらのデリゲート型か曖昧になる。 SomeMethod(TwoParamAction action) の行を有効にすると、Mainメソッドの2行目以外の型推論が効かなくなる。1行目のラムダは、2引数で値を返さない複数のデリゲート型がある場合、曖昧となる。 3行目のラムダは、代入式の左辺にあるoはstringを格納できる型でなければならないが、一方で右辺のoとeは暗黙にToString()が呼び出されるため、いずれの型であってもよく、TwoStringAction TwoParamActionの間で曖昧となる。 2行目のラムダは、oとeの間に適切なoperator+が定義されなければならず、TwoStringAction型と推論される。 SomeMethod(TwoIntegerAction action) の行を有効にすると、Mainメソッドの3行目以外の型推論が効かなくなる。2行目のラムダは、oとeはstringかintのいずれでもoperator+が実行できるため、TwoStringActionTwoIntegerActionの間で曖昧となる。 3行目のラムダは、代入式の左辺にあるoはstringを格納できる型でなければならないため、TwoStringAction型と推論される。 デリゲート型を引数に取るメソッドを複数用意する場合、オーバーロードではなく別名のメソッドとすることで、この複雑性は回避できる。
※この「無名関数の型推論の例」の解説は、「型推論」の解説の一部です。
「無名関数の型推論の例」を含む「型推論」の記事については、「型推論」の概要を参照ください。
- 無名関数の型推論の例のページへのリンク