Aaron Dail
Aaron Dail

Reputation: 33

Reflecting on a F# module when there is another Type with the same name

I am trying to get the MethodInfo for a function in a module: PersistentVector.ofSeq. The issue I am running into is that there is a generic type defined with the same name as the module: PersistentVector<'a>.

I want to do this:

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

But that fails to compile (line 1) with the error: The type 'FSharpx.Collections.PersistentVector<_>' expects 1 type argument(s) but 0 given.

If I change line 2 to this:

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

That compiles but at runtime returns null since the Type being retrieved is the generic PersistentVector type which does not have an "ofSeq" method.

I can get things to work like this:

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

But that seems hacky and I am wondering if theres a better way.

Upvotes: 3

Views: 63

Answers (1)

kvb
kvb

Reputation: 55184

Yes, it's a shame that typeof<_> can't take a module as an argument, only a type (despite that in the .NET representation modules are types). Here's an alternative approach:

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

Upvotes: 2

Related Questions