私は以下のサンプルを持っています。これが原因でエラーが発生するのはなぜですか?CS4011:型引数は使用から推測できませんか?
class Program {
static void Main(string[] args) {
var varc = new C();
// Error CS0411
var varf1b = varc.F1(t => new { City = t.City }, (t, v) => v + t.Status, (g, a) => new { City = g.City, Bigstatus = a });
// compiles OK
var varf1a = varc.F1(t => new { City = t.City }, (C t, int v) => v + t.Status, (g, a) => new { City = g.City, Bigstatus = a });
// now replace varc by an anonymous class -- how to solve it now?
var varanon = new { };
}
}
public class C {
public string City;
public int Status;
}
public static class X {
public static T1 F1<T2, T3, T4, T1>(
this T2 s,
Func<T2, T3> g,
Func<T2, T4, T4> a,
Func<T3, T4, T1> r)
where T2 : class where T3 : class where T1 : class {
return null;
}
}
最初の呼び出しでエラーCS0411が発生します。匿名型を使用しているため、型引数を追加する通常の方法ではこれを修正できません。幸いなことに、lambdaの1つに型を追加することは、コンパイラを満足させるのに十分なようです。
なぜですか?具体的には最初の例は失敗し、2番目は成功するでしょうか?
第二に、これは起こらないように関数呼び出しを書くための方法がありますか?ユーザーはラムダに型を挿入する必要がありませんか?
はい、他の人が同様の質問をしましたが、ここではユニークなのは(a)ラムダに型を追加することによる修正(b)匿名型の使用です。編集
:与えられた解決策の問題は、可能な型注釈が存在しないので、それが匿名クラスで使用することはできませんということです。
このように見て、あなたは 'v'が' int'型であることをコンパイラが知っていることを期待しています。しかし、なぜそれができるはずですか? 'T4'は簡単に' long'、 'double'、' decimal'、または加算演算子に整数でオーバーロードする他の型にすることができます。 –
@JeffMercado:いいえ、そうではありません。コンパイラは式の形式には興味がありません。エラーを変更することなく、何か(有効)で置き換えることができます。 –
私の主張は、コンパイラがあなたのために型を決めるのが遠すぎないようにすることです。少なくとも、他の言語ほどではありません。それが試しても、その選択があいまいなので成功しないでしょう。それは完全に知られているあなたが提供したタイプのみを使用します。入力タイプに関する情報を提供することはできませんが、出力タイプとそれだけでは、 'T4'は十分な情報ではない' int'を持つ 'T4'を追加した結果かもしれません。 –