C# 语言规范在第7.5.2 节中描述了类型推断。里面有一个细节我不明白。考虑以下情况:
// declaration
void Method<T>(T obj, Func<string, T> func);
// call
Method("obj", s => (object) s);
Microsoft 和 Mono C# 编译器都正确推断T
= object
,但我对规范中算法的理解会产生T
=string
然后失败。这是我的理解:
第一阶段
如果 Ei 是匿名函数,则从 Ei 到 Ti 进行显式参数类型推断(第 7.5.2.7 节)
⇒ 没有效果,因为 lambda 表达式没有明确的参数类型。正确的?
否则,如果 Ei 具有类型 U 并且 xi 是值参数,则从 U 到 Ti 进行下限推断。
⇒ 第一个参数是静态类型的
string
,所以这增加string
了 的下限T
,对吧?
第二阶段
所有不依赖于(§7.5.2.5)任何 Xj 的未固定类型变量Xi 都是固定的(§7.5.2.10)。
⇒
T
不固定;T
不依赖于任何东西......所以T
应该修复,对吧?
§7.5.2.11 固定
候选类型 Uj 的集合开始是 Xi 的边界集合中所有类型的集合。
⇒ {
string
(下限)}然后,我们依次检查 Xi 的每个界限:[...] 对于 Xi 的每个下限 U,所有类型 Uj 都从候选集中删除,其中没有从 U 隐式转换到。[...]
⇒ 不会从候选集中删除任何东西,对吧?
如果在剩余的候选类型 Uj 中存在唯一类型 V,从该类型隐式转换到所有其他候选类型,则 Xi 固定为 V。
⇒ 由于只有一种候选类型,这是空洞的,所以 Xi 固定为
string
。正确的?
那么我哪里错了?