【问题标题】:Where is the 'indeterminate type'?“不确定类型”在哪里?
【发布时间】:2010-05-05 20:44:26
【问题描述】:

我正在定义以下类型扩展:

type System.Reflection.MemberInfo with
    member x.GetAttribute<'T when 'T :> Attribute>(required, inherit') =
        match required, Attribute.GetCustomAttribute(x, typeof<'T>, inherit') with
        | true, null -> invalidOp (sprintf "Missing required attribute: %s" typeof<'T>.FullName)
        | _, attr -> attr :> 'T

最后一个匹配表达式 (attr :&gt; 'T) 给出错误:

从 Attribute 到 'T 的静态强制涉及基于此程序点之前的信息的不确定类型。某些类型不允许使用静态强制。需要进一步的类型注释。

我尝试过注释函数返回类型,但得到了相同的结果。我不想将其更改为动态演员表。有没有办法让静态演员工作?

【问题讨论】:

    标签: f#


    【解决方案1】:

    它必须是动态演员,对吧?您有一个静态类型为 System.Attribute 的对象,并且您想将其向下转换为它的实际具体类型。

    open System
    type System.Reflection.MemberInfo with 
      member x.GetAttribute<'T when 'T :> Attribute>(required, inherit') =  // '
        match required, Attribute.GetCustomAttribute(x, typeof<'T>, inherit') with 
        | true, null -> invalidOp (
            sprintf "Missing required attribute: %s" typeof<'T>.FullName)  // '
        | _, attr -> attr :?> 'T 
    

    【讨论】:

    • 我想是的。我想我被 C# 中的类似代码吓到了,其中动态和静态强制转换具有相同的语法。它也必须是 C# 中的动态转换。
    【解决方案2】:

    为了澄清错误消息的含义 - 编译器在静态转换 :&gt;(始终是安全的,例如从 Random 转换为 Object)和动态转换 :?&gt;(可能会失败)之间做出区别)。

    在您的情况下,您需要使用动态转换。这就是编译器的意思:

    • 它说“从属性到'T 的静态强制涉及一个不确定的类型”。这意味着它不知道(在编译时)用于代替泛型参数'T 的实际类型是什么。

    • 因此,编译器无法检查从Attribute'T 的转换是否总是成功(这是在静态强制的情况下所必需的)。例如,如果编译器确定 'T 的类型将始终为 Object,则使用静态强制是有效的。

    【讨论】:

      【解决方案3】:

      更正的代码,以防它对任何人都有益(Brian 的代码也是正确的......我只是更喜欢签名中的类型注释):

      type System.Reflection.MemberInfo with
          member x.GetAttribute<'T when 'T :> Attribute>(required, inherit') : 'T =
              match required, Attribute.GetCustomAttribute(x, typeof<'T>, inherit') with
              | true, null -> invalidOp (sprintf "Missing required attribute: %s" typeof<'T>.FullName)
              | _, attr -> downcast attr
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多