typeof< _>的使用活动模式 [英] Use of typeof<_> in active pattern

查看:50
本文介绍了typeof< _>的使用活动模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Given the following contrived active pattern:

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
| _ -> ()

给出错误:

模式匹配中的意外类型应用程序.预期为->"或其他令牌.

Unexpected type application in pattern matching. Expected '->' or other token.

但这可行:

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

为什么这里不允许使用 typedefof (或 typeof )?

Why is typedefof (or typeof) not allowed here?

推荐答案

即使您使用参数化的活动模式(参数是某些表达式),编译器也会将参数解析为模式(与表达式相反)),因此语法受到更多限制.

Even if you're using a parameterized active pattern (where the argument is some expression), the compiler parses the argument as a pattern (as opposed to an expression), so the syntax is more restricted.

我认为这基本上是与此处讨论的问题相同的问题:

I think this is essentially the same problem as the one discussed here: How can I pass complex expression to parametrized active pattern? (I'm not sure about the actual compiler implementation, but the F# specification says that it should parse as a pattern).

作为一种解决方法,您可以在引号内编写任何表达式,因此可以执行以下操作:

As a workaround, you can write any expression inside a quotation, so you could do this:

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
| _ -> ()

这篇关于typeof&lt; _&gt;的使用活动模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆