当存在具有相同名称的另一个类型时,反映在F#模块上

时间:2015-12-04 19:35:58

标签: f#

我正在尝试获取模块中函数的MethodInfoPersistentVector.ofSeq。我遇到的问题是定义了一个与模块名称相同的泛型类型:PersistentVector<'a>

我想这样做:

let methodInfo = typedefof<PersistentVector>.GetMethod("ofSeq")
let finalMethod = methodInfo.MakeGenericMethod(itemType)
finalMethod.Invoke(...)

但是无法编译(第1行),错误为:The type 'FSharpx.Collections.PersistentVector<_>' expects 1 type argument(s) but 0 given.

如果我将第2行更改为:

let methodInfo = typedefof<PersistentVector<_>>.GetMethod("ofSeq")

编译但在运行时返回null,因为正在检索的Type是通用的PersistentVector类型,它没有“ofSeq”方法。

我可以这样开展工作:

let pvModuleTypeFullName = "FSharpx.Collections.PersistentVectorModule"
let pvModuleType = Assembly.GetAssembly(typedefof<PersistentVector<_>>).GetType(pvModuleTypeFullName)
let methodInfo = pvModuleType.GetMethod("ofSeq")
let finalMethod = methodInfo.MakeGenericMethod(itemType)
finalMethod.Invoke(...)

但这看起来很糟糕,我想知道是否有更好的方式。

1 个答案:

答案 0 :(得分:2)

是的,遗憾的是typeof<_>无法将模块作为参数,只有一种类型(尽管.NET表示模块中的 类型)。这是另一种方法:

open Quotations.Patterns
let finalMethod = 
    let (Lambda(_,Call(None,m,[_]))) = <@ PersistentVector.ofSeq @>
    m.GetGenericMethodDefinition().MakeGenericMethod(itemType)
...