如何在F#中将引用编译为新类型的公共静态方法

时间:2011-09-23 10:42:30

标签: f# f#-3.0

我正在使用类型提供程序,我正在尝试将引用编译为新生成类型的公共静态方法。这就是我所拥有的:

let CreateType<'i> name methodName quotation =
    let assemblyName = new AssemblyName(Name = "tmpAssembly")
    let assemblyBuilder = 
        System.AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave)

    let filename = "tmpAssembly.dll"
    let tmpModule = assemblyBuilder.DefineDynamicModule(filename,filename)

    // create a new type builder
    let typeBuilder = 
        tmpModule.DefineType(
            name, 
            TypeAttributes.Public ||| TypeAttributes.Class,
            null, // parentType
            [|typeof<'i>|])

    let attr = MethodAttributes.Public ||| MethodAttributes.HideBySig ||| MethodAttributes.Static

    let methodImpl = 
        typeBuilder.DefineMethod(
            methodName, 
            attr, 
            typeof<unit>, // todo
            [||])  // todo

    let il = methodImpl.GetILGenerator()

    // compile quotation to method

    typeBuilder.CreateType()

我知道有.Compile()方法,但我认为这不是我需要的。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

我还没有真正使用过F#3.0版本,但我认为你不需要自己生成IL代码。 post by Keith解释了有两种类型的类型提供程序 - 生成创建一个真正的.NET类型(存在于某些库中)和擦除创建一个假类型然后给编译器一个表达树来代替对假类型的调用。

在我看来,您正试图在擦除类型更合适的情况下实现生成的类型提供程序。在擦除的情况下,您应该只能返回.NET Expression<..>类型(不是F#引用,但您可以使用PowerPack中的ToLinqExpression),F#编译器将为您编译。

但是,我还没有玩过它,所以我不知道确切的机制是什么。