'不确定型'在哪里?

时间:2010-05-04 15:00:38

标签: f#

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

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 :> 'T)给出错误:

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

我试过注释函数返回类型,但得到了相同的结果。我不想把它改成动态演员。有没有办法使静态演员工作?

3 个答案:

答案 0 :(得分:3)

它必须是一个动态演员,对吧?您有一个静态类型为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 

答案 1 :(得分:1)

为了澄清错误消息的含义 - 编译器在静态转换:>(总是安全的,例如从Random转换为Object)和动态转换{之间的区别。 {1}}(可能会失败)。

在您的情况下,您需要使用动态强制转换。这就是编译器的含义:

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

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

答案 2 :(得分:0)

更正后的代码,以防任何人受益(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