代码之家  ›  专栏  ›  技术社区  ›  Timwi

理解语言规范中描述的C#类型推理的问题

  •  62
  • Timwi  · 技术社区  · 14 年前

    这个 C# language specification 第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是匿名函数 显式参数类型推断 (§7.5.2.7)由Ei至Ti制成

      没有效果,因为lambda表达式没有显式参数类型。对吗?

    • 否则,如果EI具有类型u和席是一个值参数,那么 从U到Ti。

      第一个参数是静态类型 一串 一串 ,对吧?

    第二阶段

    • 全部 不固定 键入不包含 依靠 (§7.5.2.5)任何Xj都是固定的(§7.5.2.10)。

      T型 T型 不依赖任何东西。。。所以 T型

    • 候选类型集Uj从Xi的边界集中的所有类型集开始。

      一串

    • 然后,我们依次检查Xi的每一个界:[…]对于Xi的每一个下界U,从候选集中移除所有类型Uj,其中没有从U的隐式转换。[...]

      不会从候选集中删除任何内容,对吗?

    • 因为只有一个候选类型,这是完全正确的,所以Xi被固定为 . 对吗?


    1 回复  |  直到 14 年前
        1
  •  41
  •   Eric Lippert    14 年前

    更新:我今早对巴士的初步调查是不完整和错误的。第一阶段规范的文本是正确的。执行是正确的。

    规范是错误的,因为它在第二阶段错误地获得了事件的顺序。我们应该指定进行输出类型推断 我们修正了非相依参数。

    伙计,这东西很复杂。我已经重写了规范的这一部分的次数超过了我的记忆。

    我将与Mads一起更新规范以匹配实现。我认为第二阶段的正确措辞应该是这样的:

    • 如果不存在不固定的类型参数,则类型推断成功。
    • 否则,如果存在一个或多个参数Ei 相应的参数类型Ti 类型为Ti的Ei的输出类型至少包含一个非固定类型 类型参数Xj,和 类型为Ti的Ei的输入类型都不包含任何未固定的 然后从所有这些Ei到Ti进行输出类型推断。

    现在必须修复至少一个类型参数,如下所示:

    • 如果存在一个或多个类型参数Xi,则 Xi不依赖任何Xj 那么每个这样的Xi都是固定的。如果任何修复操作失败
    • 否则,如果存在一个或多个类型参数Xi,则 Xi有一个非空的边界集,并且 至少有一个类型参数Xj依赖于Xi 那么每个这样的Xi都是固定的。如果任何修复操作失败
    • 否则,我们就无法取得进展,也就没有进展

    如果类型推断既没有失败也没有成功,那么第二阶段将重复。

    谢谢你引起我的注意。