如何获取GenericInstanceType的方法?

时间:2017-10-13 13:29:14

标签: f# mono.cecil

open System
open System.Runtime.CompilerServices
open Mono.Cecil
open Mono.Cecil.Rocks

type SpiralType =
    | IntT
    | StringT
    | TupleT of SpiralType list

let module_ = ModuleDefinition.CreateModule("TypeTokenFactory",ModuleKind.Console)
let r1 = module_.ImportReference(typeof<obj>)
let r2 = module_.ImportReference(typeof<obj>)

let table = ConditionalWeakTable()
table.Add(r1,IntT)
table.Add(r2,StringT)

let mscorlib_path = @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll"
let mscorlib = AssemblyDefinition.ReadAssembly(mscorlib_path)

let dictionary_type =
    mscorlib.Modules.[0].Types
    |> Seq.find (fun x -> x.Name = "Dictionary`2")

let dict_ins = dictionary_type.MakeGenericInstanceType([|r1;r2|])
// Lacks the Methods field...

我一直在努力弄清楚如何使上述工作与System.Type一起使用,但现在我正在尝试使用Mono.Cecil。关于我想要做的事情的一些历史,请看看我在SO的最后two questions以及我在F#repo上打开的issue很深的。

让我在这里简要总结一下:为了与我正在使用的语言集成,我需要能够查询.NET程序集的类型,并替换类和方法的泛型参数。 / p>

现在,我不需要替换确切的类型。如上面的示例所示,将元数据附加到虚拟类型对于我的目的来说已经足够了,但现在我遇到了与System.Type不同的问题,一旦我替换了泛型参数,我就无法再查询关于类型的方法。

如此接近。有没有办法让这个工作Mono.Cecil?或者,我很高兴知道是否可以使用其他库。我完全不需要Cecil的程序集编辑功能。

1 个答案:

答案 0 :(得分:2)

Cecil为您提供了相对较低级别的元数据视图。

Cecil将为您提供表示程序集中不同元数据结构的方法,但不提供类型的运行时表示形式。

要回答你的问题,它不会告诉你实例化泛型类型的方法,因为这是一个运行时构造,而不是元数据中可用的东西。

像System.Reflection或IKVM.Reflection这样的高级API将会这样做。