如何在 F# 中将引用编译为新类型的公共静态方法
我正在使用类型提供程序,并尝试将引用编译为新生成类型的公共静态方法。这就是我所拥有的:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我还没有真正使用过 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 useToLinqExpression
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.