如何解决从当前正在生成的程序集中检索使用GenericTypeParameterBuilder类型的函数委托类型
我正在尝试使用System.Reflection.Emit中提供的API在F#中进行编译。当我尝试从当前正在构建的程序集中创建使用GenericTypeParameterBuilder类型的函数(代理)时遇到问题。转换以下Java(Java的略微修改版本)类的示例:
class A extends Object {
A () {}
Function<A,A> fun() {
return (A a) -> { return a; }; // OK
}
}
class B<X extends Object> extends Object {
X val;
B (X val) { this.val = val; }
Function<X,X> fun() {
return (X x) -> { return x; }; // does not work to translate
}
}
因此,我需要能够使用Func 和Func
callvirt instance !1 class [mscorlib]System.Func`2<class A,class A>::Invoke(!0)
callvirt instance !1 class [mscorlib]System.Func`2<!X,!X>::Invoke(!0)
let deleg = System.Linq.Expressions.Expression.GetFuncType(types)
let method = deleg.GetConstructor([|typeof<obj> ; typeof<nativeint>|]).DeclaringType.getmethod("Invoke")
ilGenerator.Emit(OpCodes.Callvirt,method)
其中types
是System.Type元素的数组。对于Func ,类型数组为[|typeBuilder.GetType() ; typeBuilder.GetType()|]
,但是对于类B中的Func [|genericTypeParameterBuilder.GetType() ; genericTypeParameterBuilder.GetType()|]
}数组会生成一条奇怪的CIL指令(程序集仍在构建中,但是指令错误):
types
生成类A的typeBuilder的方式是:
callvirt instance !1 class [mscorlib]System.Func`2<class [mscorlib]System.Reflection.Emit.GenericTypeParameterBuilder,class [mscorlib]System.Reflection.Emit.GenericTypeParameterBuilder>::Invoke(!0)
类型B也会发生这种情况,多余的let typeBuilder = moduleBuilder.DefineType(typ,TypeAttributes.Public ||| TypeAttributes.Class)
typeBuilder.SetParent(typeof<obj>)
let constrBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.Standard,[||])
let methodBuilder = typeBuilder.DefineMethod("fun",MethodAttributes.Public)
let delegRetType = System.Linq.Expressions.Expression.GetDelegateType([|typeof<obj> ; typeof<int>|]).GetConstructor([|typeBuilder.GetType() ; typeBuilder.GetType()|]).DeclaringType
methodBuilder.SetReturnType(delegRetType)
methodBuilder.SetParameters([||])
//buildConstrBody - nothing special
//buildMethodBody - generating the instructions using the methodBuilder .GetILGenerator() - using varIoUs System.Func types
typeBuilder.CreateType()
的构造是这样的,没有修饰符或限制:
genericTypeParameterBuilder
我构建类型数组的方式是使用以下函数:
let genericTypeParameterBuilder = typeBuilder.DefineGenericParameters([|"X"|]).[0]
控制台:
let rec typesForFuncRec (types: System.Type list) : System.Type list =
match types with
| [] -> []
| typ :: rest ->
match typ with
| :? GenericTypeParameterBuilder as gtpb ->
printfn "generic GetType() : %O" (gtpb.GetType())
printfn "generic :> : %O" (gtpb :> System.Type)
printfn "generic ReflectedType : %O" (gtpb.ReflectedType)
printfn "generic UnderlyingSystemType : %O" (gtpb.UnderlyingSystemType)
printfn "generic MakeByRefType() : %O" (gtpb.MakeByRefType())
gtpb.GetType() :: (typesForFuncRec rest)
| :? TypeBuilder as tb -> tb.GetType() :: (typesForFuncRec rest)
| _ -> typ :: (typesForFuncRec rest)
;;
我还尝试使用generic GetType() : System.Reflection.Emit.GenericTypeParameterBuilder
generic :> : X
generic ReflectedType : B[X]
generic UnderlyingSystemType : X
generic MakeByRefType() : X&
和gtpb.GetType()
来代替gtpb :> System.Type
,它们会引发以下错误:
gtpb.UnderlyingSystemType
我也尝试过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,ParameterModifier[] modifiers)
,它会引发以下错误:
gtpb.MakeByRefType()
问题是:
-
(不那么重要,我只是好奇)对于常规类类型生成器的System.Func,为什么我需要在其他操作中将System.Type检索为
System.ArgumentException: type must not be ByRef at System.Linq.Expressions.Expression.GetFuncType(Type[] typeArgs)
(方法返回类型/参数类型),我只能使用强制转换:typeBuilder.GetType()
??
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。