如何在 Reflection.Emit 中使用带有运行时定义类型参数的泛型类型

问题描述 投票:0回答:1

在 .NET 8 下运行此程序。

IJoinable<T1, T2>
已经作为通用接口存在于代码库中。它声明了一种方法,
T2 Join(T1 value)
。用于类型参数的类型(
lType
rType
joinedType
)是在运行时动态生成的 TypeBuilder 变量。

    var joinType = typeof(IJoinable<,>).MakeGenericType(rType, joinedType);
    lType.AddInterfaceImplementation(joinType);
    var joinMethod = lType.DefineMethod("Join", MethodAttributes.Public | MethodAttributes.Virtual, joinedType, [rType]);
    var gen = joinMethod.GetILGenerator();
    gen.Emit(OpCodes.Ldarg_0);
    gen.Emit(OpCodes.Ldarg_1);
    gen.Emit(OpCodes.Call, ctor);
    gen.Emit(OpCodes.Ret);
    lType.DefineMethodOverride(joinMethod, joinType.GetMethod("Join")!);

当我在最后一行调用

joinType.GetMethod()
时,它会抛出
NotSupportedException
,因为不知何故它最终出现在
System.Reflection.Emit.TypeBuilderInstantiation.GetMethodImpl()
内部,而其整个方法体就是抛出
NotSupportedException

如果这不起作用,正确的方法是什么?

c# .net-core reflection.emit
1个回答
1
投票

为了执行涉及 Reflection.Emit 和泛型的操作,

TypeBuilder
上存在三个有些隐藏但显而易见的静态方法:

  • TypeBuilder.GetMethod
  • TypeBuilder.GetConstructor
  • TypeBuilder.GetField

这些方法作用于

TypeBuilderInstantiation
对象。因此,使用经典
GetMethod
方法失败的调用需要替换为如下所示:

var genericMethod = TypeBuilder.GetMethod(joinType, typeof(IJoinable<,>).GetMethod("Join"));

实际上,我认为这些方法的文档非常好(TypeBuilder.GetMethod)。然而,它们偏离了 Reflection.Emit API 其他部分建立的模式,使得它们有点难以找到。

© www.soinside.com 2019 - 2024. All rights reserved.