2013-03-29 12 views
6

型推論について少し調べましたが、私の特定の問題に解決策を適用できないようです。ネストされたジェネリック関数の型推論

私は、関数を構築したり渡したりするのに多くの作業をしています。これはint型を推測することができるはずです。私が考えることができる唯一のことは、ラムダ戻り型が型推論アルゴリズムでチェックされていないということです。問題をより明確に示すために、私は不要なロジックを取り除いた。

Func<T> Test<T>(Func<Func<T>> func) 
{ 
    return func(); 
} 

これはコンパイル:

Func<int> x = Test<int>(() => 
    { 
     int i = 0; 
     return() => i; 
    }); 

をしかし、これはエラーになります「メソッドの型引数は、使用から推測することはできません明示的に型引数を指定してみてください。」:

Func<int> x = Test(() => 
    { 
     int i = 0; 
     return() => i; 
    }); 

私はちょうどそれがなぜこの方法およびあらゆる回避策を働かせるか知りたいと思う。

+0

非常によく似た質問ですが、全く同じではありませんhttp://stackoverflow.com/questions/6090159/inferring-generic-types-with-functional-composition –

答えて

7

私は質問に対する正しい答えがSO Why can't an anonymous method be assigned to var?

にE.Lippertによって与えられていると言う。しかし、私たちは少しあなたの例で遊ばせます:

Func<Func<int>> f =() => 
{ 
    int i = 0; 
    return() => i; 
}; 

Func<int> x = Test(f); //it compiles OK 

と型推論問題なしあなたFunc<T> Test<T>(Func<Func<T>> func)ここに。 匿名のラムダ式を使用しているため、そのタイプは推測できません。これを試してみてください:それはCompiler Error CS0815を与える

var f =() => 
{ 
    int i = 0; 
    return() => i; 
}; 

暗黙に型付けされたローカル変数

と説明をラムダ式を割り当てることができませんがあると言って:

アンを暗黙的に型指定されたの初期化子として使用される式変数には型が必要です。匿名関数式、 メソッドグループ式、およびNULLリテラル式には 型がないため、適切な初期化子ではありません。暗黙的に型指定された 変数は、後でnullの値を割り当てることはできますが、その宣言ではNULL値で初期化することはできません。

今度は、別のものを試してみましょう:

var x = Test(() => 
{ 
    Func<int> f =() => 0; 
    return f; 
}); 

それだけでなく、コンパイルします。

return() => i; 

我々はさらに行くことができるとエリックリペットは彼の答えに言っていることによると、このラップする別の関数を提供::私たちは今、

static Func<T> GetFunc<T>(Func<T> f) { return f; } 

をだからあなたの元の例の問題点は、この行を実際にしました

var x = Test(() => 
{ 
    int i = 0; 
    return GetFunc(() => i); 
}); 

このようにコードを書き換えることができます。

しかし、私が理解する限り、これはすべてオーバーヘッドであり、明示的な型を提供するだけです。これらの回避策はラムダが必要なときに適していますが、匿名型のオブジェクトを返すことができます。

関連する問題