9

STが異なる場合、これは機能します。

public static void Fun<S, T>(Func<S, T> func)
{

}

Fun((string s) => true); //compiles, T is inferred from return type.

しかし、

public static void Fun<T>(Func<T, T> func)
{

}

Fun(t => true); //can't infer type.

最初の例でTは、ラムダ式の戻り値の型から推論してTいるので、2番目の例でも推論できないのでしょうか? 私はそれをやっていると思いますが、なぜ最初のTことがわかっていないのに、2番目TFunc<T, T>ことがわかっているのT == Tですか?または、s の場合に推論される型の順序はありFuncますか?

4

2 に答える 2

13

S と T が異なることとは何の関係もありません。最初のケースでは仮パラメータ型を指定し、2 番目のケースでは指定しないことに関係しています。

メソッドの型の推定では、デリゲートの仮パラメーターの型が判明するまで、ラムダからデリゲートの戻り値の型を推測しようとしません。

2 番目のケースでは、正式なパラメーターの型 T を推論するためにコンパイラーに何も与えていないため、ラムダの本体は分析されません。

「仮パラメータ型」とはどういう意味ですか?

仮パラメーターは、メソッド、インデクサー、コンストラクター、ラムダ、または匿名メソッドに渡される引数の値を取る変数です。(または、outおよびref仮パラメーターの場合は、呼び出し元によって提供される変数のエイリアスになります。) 仮パラメーターは変数であるため、型があります

デリゲートには、 typeのdelegate R Func<A, R>(A a);仮パラメーターがあります。make するメソッド型パラメーターを使用してそれを構築するため、デリゲートの仮パラメーター型は になります。型推論のタスクは、これらの型とを推論することです。aAFunc<S, T>SST

s最初の例では、 type の仮パラメーターを持つラムダがありますstring。したがって、このラムダ引数funcは method の仮パラメーターに対応しFun、 の仮パラメーターの型はfuncFunc<S, T>仮パラメーターの型は にs対応する必要があるため、型推論の理由はSです。の正式なパラメータ タイプを指定したためsSは であると推測されますstring

その推論が行わTれると、ラムダの本体を分析することで推論できます。

2番目のケースでは、に指定された正式なパラメータータイプはありませんt。の型を推測できるものは他にないためt、型推論は断念し、本体を見る前にこのラムダの分析を放棄します。

あなたの場合、ラムダの正式なパラメーターの型とは無関係に本体を分析できることがたまたまありました。これはまれなケースであり、型推論アルゴリズムはそれを利用するように作成されていません。

これが必要なタイプの推論である場合は、C# の代わりに F# を使用することを検討してください。Hindley-Milner アルゴリズムに基づく、はるかに高度な型推論アルゴリズムを備えています。

于 2013-02-12T17:08:35.373 に答える
5

ラムダやその他の関数のジェネリック パラメーターは、戻り値の型ではなく、パラメーターの型によって決まります。これができないのとまったく同じ理由です:

T Foo<T>() { return default(T); }

string x = Foo(); // error

式 については、t => true何が考えられるかは明らかにわからないtため、コンパイラーはこれだけに基づいてこれ以上決定を下すことができません。

于 2013-02-12T16:45:22.867 に答える