在活动模式中使用 typeof<_>

2024-04-05

给出以下人为的活动模式:

let (|TypeDef|_|) (typeDef:Type) (value:obj) =
  if obj.ReferenceEquals(value, null) then None
  else
    let typ = value.GetType()
    if typ.IsGenericType && typ.GetGenericTypeDefinition() = typeDef then Some(typ.GetGenericArguments())
    else None

下列:

let dict = System.Collections.Generic.Dictionary<string,obj>()
match dict with
| TypeDef typedefof<Dictionary<_,_>> typeArgs -> printfn "%A" typeArgs
| _ -> ()

给出错误:

模式匹配中的意外类型应用。应为“->”或其他标记。

但这有效:

let typ = typedefof<Dictionary<_,_>>
match dict with
| TypeDef typ typeArgs -> printfn "%A" typeArgs
| _ -> ()

Why is typedefof (or typeof)这里不允许?


即使您使用参数化活动模式(其中参数是某个表达式),编译器也会将参数解析为模式(而不是表达式),因此语法受到更多限制。

我认为这本质上与这里讨论的问题相同:如何将复杂表达式传递给参数化活动模式? https://stackoverflow.com/questions/6168851/how-can-i-pass-complex-expression-to-parametrized-active-pattern(我不确定实际的编译器实现,但 F# 规范表示它应该解析为模式)。

作为解决方法,您可以在引用中编写任何表达式,因此您可以这样做:

let undef<'T> : 'T = Unchecked.defaultof<_>

let (|TypeDef|) (typeExpr:Expr) (value:obj) =
  let typeDef = typeExpr.Type.GetGenericTypeDefinition()
  // ...

let dict = System.Collections.Generic.Dictionary<string,obj>()
match dict with
| TypeDef <@ undef<Dictionary<_,_>> @> typeArgs -> printfn "%A" typeArgs
| _ -> ()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在活动模式中使用 typeof<_> 的相关文章

随机推荐