次のコードがあります:
Func<string, bool> comparer = delegate(string value) {
return value != "0";
};
ただし、次のコードはコンパイルされません。
var comparer = delegate(string value) {
return value != "0";
};
なぜコンパイラはそれが であることを理解できないのでしょうかFunc<string, bool>
? 1 つの文字列パラメータを受け取り、ブール値を返します。代わりに、次のエラーが発生します:
暗黙的に型指定されたローカル変数に匿名メソッドを割り当てることはできません。
一つ推測できるのはvarバージョンがコンパイルされた場合次のような場合は一貫性が欠けます。
var comparer = delegate(string arg1, string arg2, string arg3, string arg4, string arg5) {
return false;
};
Func<> では最大 4 つの引数しか許可されないため (私が使用している .NET 3.5 の場合)、上記は意味をなさないでしょう。おそらく誰かがこの問題を明確にしてくれるでしょう。ありがとうございます。
ベストアンサー1
更新: この回答は 10 年以上前に書かれたもので、歴史的に興味深いものと考えるべきです。C# 10 では、コンパイラーはいくつかのデリゲート型を推論します。
他の人はすでに、デリゲートできるデリゲートの種類は無限にあると指摘しています。できた何を意味しているのでしょうか。またはまたは他の可能性Func
の代わりにこれがデフォルトになるに値するほど特別なことは何でしょうか。また、ラムダの場合、式ツリー形式ではなくデリゲート形式を選択する意図があることが明らかなのはなぜでしょうか。Predicate
Action
しかし、これは特別であり、ラムダまたは匿名メソッドの推論された型は何かの Func であると言うこともできますFunc
。それでも、さまざまな問題が残ります。次のケースでは、どのような型を推論したいですか?
var x1 = (ref int y)=>123;
Func<T>
ref anything を受け取る型はありません。
var x2 = y=>123;
戻り値はわかっていますが、仮パラメータの型はわかりません。(それともわかっていますか? 戻り値は int ですか? long ですか? short ですか? byte ですか?)
var x3 = (int y)=>null;
戻り値の型は不明ですが、void にすることはできません。戻り値の型は、任意の参照型または任意の null 許容値型にすることができます。
var x4 = (int y)=>{ throw new Exception(); }
今回も戻り値の型は不明で、できる無効となります。
var x5 = (int y)=> q += y;
これは、void を返すステートメント lambda を意図したものでしょうか、それとも q に割り当てられた値を返すものでしょうか? どちらも有効ですが、どちらを選択すべきでしょうか?
さて、あなたは、これらの機能をサポートしないで、型が解決できる「通常の」ケースだけをサポートすればいいと言うかもしれません。それでは役に立ちません。それで何が楽になるのでしょうか?機能が時々機能し、時々失敗するのであれば、私は依然としてコードを書かなければなりません。検出するこれらすべての失敗状況と意味のあるエラーメッセージそれぞれについて。その動作をすべて指定し、文書化し、テストを書くなどしなければなりません。これは非常に高価な機能これにより、ユーザーはおそらく 6 回ほどキー入力を節約できます。半分は機能せず、機能する場合でもほとんどメリットがない機能のテスト ケースの作成に多くの時間を費やすよりも、言語に価値を追加する方がよい方法があります。
実際に役立つ状況は次のとおりです。
var xAnon = (int y)=>new { Y = y };
なぜなら、その物には「話せる」型がないからです。しかし、この問題は常に発生しており、メソッド型推論を使用して型を推測します。
Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });
そしてメソッド型推論により、 func 型が何であるかが判定されます。