F# 使用自定义类型从当前正在生成的程序集检索委托类型

F# 使用自定义类型从当前正在生成的程序集检索委托类型,f#,delegates,system.reflection,cil,F#,Delegates,System.reflection,Cil,我正试图使用System.Reflection.Emit中提供的API在F#中制作一个编译器。当我尝试为当前正在构建的程序集中的类型创建函数(委托)时,遇到了一个问题。翻译以下Java(Java的稍微修改版本)类的示例: 如果我需要为使用.NET类型的函数生成相同的指令,例如Func,那么上面的代码工作得很好(在本例中,类型数组是types=[|typeof;typeof |])。任何关于上述解决方案不起作用的建议,或关于如何检索系统的任何其他替代方案。类型生成器(未完成构建)都是非常受欢迎的

我正试图使用System.Reflection.Emit中提供的API在F#中制作一个编译器。当我尝试为当前正在构建的程序集中的类型创建函数(委托)时,遇到了一个问题。翻译以下Java(Java的稍微修改版本)类的示例:

如果我需要为使用.NET类型的函数生成相同的指令,例如Func,那么上面的代码工作得很好(在本例中,类型数组是
types=[|typeof;typeof |]
)。任何关于上述解决方案不起作用的建议,或关于如何检索系统的任何其他替代方案。类型生成器(未完成构建)都是非常受欢迎的

类A的typeBuilder的生成方式为:

let typeBuilder = moduleBuilder.DefineType(typ, TypeAttributes.Public ||| TypeAttributes.Class)
typeBuilder.SetParent(typeof<obj>)
typeBuilder.DefineField("x", typeof<int>, FieldAttributes.Public)
let constrBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, [|typeof<int>|])
let methodBuilder = typeBuilder.DefineMethod("fun", MethodAttributes.Public)
let delegRetType =  System.Linq.Expressions.Expression.GetDelegateType([|typeof<obj> ; typeof<int>|]).GetConstructor([|typeof<obj> ; typeof<nativeint>|]).DeclaringType
methodBuilder.SetReturnType(delegRetType) 
methodBuilder.SetParameters([||])
//buildConstrBody - nothing special
//buildMethodBody - generating the instructions using the methodBuilder .GetILGenerator() - triggering the error described above
typeBuilder.CreateType()
let typeBuilder=moduleBuilder.DefineType(typ,TypeAttributes.Public | | | TypeAttributes.Class)
typeBuilder.SetParent(typeof)
typeBuilder.DefineField(“x”,typeof,FieldAttributes.Public)
让constrBuilder=typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.Standard,[| typeof |])
让methodBuilder=typeBuilder.DefineMethod(“有趣”,MethodAttributes.Public)
让delegRetType=System.Linq.Expressions.Expression.GetDelegateType([| typeof;typeof |]).GetConstructor([| typeof;typeof |]).DeclaringType
methodBuilder.SetReturnType(delegRetType)
methodBuilder.SetParameters([| |])
//身体-没什么特别的
//buildMethodBody-使用methodBuilder.GetILGenerator()生成指令-触发上述错误
typeBuilder.CreateType()
请注意,
delegRetType
实际上是Func而不是Func。如果我尝试将其更改为后者,则会触发相同的错误

如果我需要为使用.NET类型的函数生成相同的指令,例如Func,那么上面的代码工作得很好(在本例中,类型数组是
types=[|typeof;typeof |]


TypeBuilder
继承自
Type
,因此,当需要对该类型进行引用时,只需传递表示正在生成的类型的实例。换句话说,您想要的数组是
types=[|typeBuilder:>System.Type;typeof |]

如果数组是这样构建的,它实际上可以工作:

types = [| typeBuilder.GetType(); typeof<int> |]
types=[| typeBuilder.GetType();typeof |]

这很难调试,因为您没有共享我们可以尝试运行的代码,但我注意到错误消息说,
无法加载类型“a”(…),因为父类型是密封的。
。您用于
A
的父类型是什么?这是密封类型吗?不,不是,该类的父类是对象类,它只是扩展了从
typeof
检索的F#System.type。但是类型A有一个用于封装函数的嵌套类,声明如下:
让nestedTypeBuilder=classTypeBuilder.DefinesTedType(cls,TypeAttributes.AutoClass | | | | TypeAttributes.AnsiClass | | TypeAttributes.NestedPublic)
,但是,即使我删除了密封的修改器,错误仍然存在……我编辑了文章,提供了有关代码的更多信息。密封父级的错误不再触发(不知道为什么)。我希望现在我的问题更清楚,因为我发布了一个使用.NET类型的简单示例。但是为什么
upcast typeBuilder
不能工作呢?
let deleg = System.Linq.Expressions.Expression.GetDelegateType(types)
let constr = deleg.GetConstructor([|typeof<obj> ; typeof<nativeint>|])
ilGenerator.Emit(OpCodes.Newobj, constr) 
System.NotSupportedException: Specified method is not supported.
at System.Reflection.Emit.TypeBuilderInstantiation.GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
let typeBuilder = moduleBuilder.DefineType(typ, TypeAttributes.Public ||| TypeAttributes.Class)
typeBuilder.SetParent(typeof<obj>)
typeBuilder.DefineField("x", typeof<int>, FieldAttributes.Public)
let constrBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, [|typeof<int>|])
let methodBuilder = typeBuilder.DefineMethod("fun", MethodAttributes.Public)
let delegRetType =  System.Linq.Expressions.Expression.GetDelegateType([|typeof<obj> ; typeof<int>|]).GetConstructor([|typeof<obj> ; typeof<nativeint>|]).DeclaringType
methodBuilder.SetReturnType(delegRetType) 
methodBuilder.SetParameters([||])
//buildConstrBody - nothing special
//buildMethodBody - generating the instructions using the methodBuilder .GetILGenerator() - triggering the error described above
typeBuilder.CreateType()
types = [| typeBuilder.GetType(); typeof<int> |]