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

发布于 2024-12-06 15:50:46 字数 1096 浏览 0 评论 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() 方法,但我认为这不是我需要的。有什么想法吗?

I am playing with type providers and I am trying to compile a quotation into a public static method of a new generated type. Here is what I have:

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

I know there is a .Compile() method but I think that's not what I need. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゞ记忆︶ㄣ 2024-12-13 15:50:46

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

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

不过我还没玩过,所以不知道具体机制是什么。

I haven't really played with the F# 3.0 release yet, but I think that you don't need to generate IL code yourself. The post by Keith explains that there are two types of type providers - generated that create a real .NET type (that exists in some library) and erased that create a fake type and then give the compiler an expression tree to be used in place of the calls to the fake type.

It seems to me that you're trying to implement generated type provider in a situation where erased type would be more appropriate. In the erased case, you should be just able to return the .NET Expression<..> type (not the F# quotation though, but you can use ToLinqExpression from PowerPack) and the F# compiler will compile that for you.

However, I haven't played with it yet, so I don't know what's the exact mechanism.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文