私はこの記事を通して自分の道を歩もうとしてきました:
http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx
...そして、1ページ目の何かが私を不快にさせました。特に、私は Compose<>() 関数に頭を悩ませようとしていたので、自分用に例を書きました。次の 2 つの Func を考えてみましょう。
Func<double, double> addTenth = x => x + 0.10;
Func<double, string> toPercentString = x => (x * 100.0).ToString() + "%";
問題ない!この2つが何をするのかを理解するのは簡単です。
ここで、記事の例に従って、次のように、これらの関数を構成する汎用拡張メソッドを記述できます。
public static class ExtensionMethods
{
public static Func<TInput, TLastOutput> Compose<TInput, TFirstOutput, TLastOutput>(
this Func<TFirstOutput, TLastOutput> toPercentString,
Func<TInput, TFirstOutput> addTenth)
{
return input => toPercentString(addTenth(input));
}
}
罰金。だから今、あなたは言うことができます:
string x = toPercentString.Compose<double, double, string>(addTenth)(0.4);
そして、文字列「50%」を取得します
ここまでは順調ですね。
しかし、ここにはあいまいなことがあります。別の拡張メソッドを作成すると、次の 2 つの関数が作成されたとします。
public static class ExtensionMethods
{
public static Func<TInput, TLastOutput> Compose<TInput, TFirstOutput, TLastOutput>(
this Func<TFirstOutput, TLastOutput> toPercentString,
Func<TInput, TFirstOutput> addTenth)
{
return input => toPercentString(addTenth(input));
}
public static Func<double, string> Compose<TInput, TFirstOutput, TLastOutput>(this
Func<double, string> toPercentString,
Func<double, double> addTenth)
{
return input => toPercentString(addTenth(input + 99999));
}
}
ここが曖昧です。これら 2 つの関数の署名が重複していませんか? はい。これでもコンパイルできますか?はい。どっちが呼ばれる?2番目のもの(明らかに「間違った」結果が得られます)が呼び出されます。いずれかの関数をコメント アウトしても、コンパイルは実行されますが、異なる結果が得られます。
つまらないことのようですが、ここには私の感性を深く怒らせる何かがあり、指を置くことはできません. 拡張メソッドと関係がありますか?ラムダと関係がありますか?それとも、 Func<> を使用して戻り値の型をパラメーター化する方法と関係がありますか? わからない。
これはすべて仕様のどこかで対処されていると思いますが、これを見つけるためにGoogleが何をすべきかさえわかりません.
ヘルプ!