当我遇到一个我不理解的类型推断错误时,我正在玩一个爱好项目。我已将其简化为以下简单示例。
我有以下类和功能:
class Foo { }
class Bar { }
class Baz { }
static T2 F<T1, T2>(Func<T1, T2> f) { return default(T2); }
static T3 G<T1, T2, T3>(Func<T1, Func<T2, T3>> f) { return default(T3); }
现在考虑以下示例:
// 1. F with explicit type arguments - Fine
F<Foo, Bar>(x => new Bar());
// 2. F with implicit type arguments - Also fine, compiler infers <Foo, Bar>
F((Foo x) => new Bar());
// 3. G with explicit type arguments - Still fine...
G<Foo, Bar, Baz>(x => y => new Baz());
// 4. G with implicit type arguments - Bang!
// Compiler error: Type arguments cannot be inferred from usage
G((Foo x) => (Bar y) => new Baz());
最后一个示例产生编译器错误,但在我看来,它应该能够毫无问题地推断类型参数。
问题:为什么编译器<Foo, Bar, Baz>
在这种情况下不能推断?
更新:我发现简单地将第二个 lambda 包装在一个标识函数中会导致编译器正确推断所有类型:
static Func<T1, T2> I<T1, T2>(Func<T1, T2> f) { return f; }
// Infers G<Foo, Bar, Baz> and I<Bar, Baz>
G((Foo x) => I((Bar y) => new Baz()));
为什么它可以完美地完成所有单独的步骤,而不是一次完成整个推理?编译器分析隐式 lambda 类型和隐式泛型类型的顺序是否有一些微妙之处?