gpt4 book ai didi

c# - ILGenerator.DeclareLocal() 采用尚未编译的类的类型

转载 作者:太空狗 更新时间:2023-10-29 18:32:15 26 4
gpt4 key购买 nike

考虑为我自己的语言制作编译器,我尝试使用 Reflection.Emit 框架生成一些 MSIL 代码。当我声明局部变量时使用 int 时它工作正常。但是,当我想声明一个尚未编译的类型的局部变量时,我遇到了麻烦,因为 DeclareLocal()Type 作为参数。那是我未编译的类,比如 A,仍然需要使用

定义
 assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemName, AssemblyBuilderAccess.RunAndSave);
module = assemblyBuilder.DefineDynamicModule(Filename);
module.DefineType(name, TypeAttributes.Public | TypeAttributes.Class)

那么我将如何编译以下程序

class A {
void M() { B b = new B(); }
}
class B
void M() { A a = new A(); }
}

最佳答案

您在这里需要的主要见解是 TypeBuilder 派生自 Type。因此,即使您尚未确定类型(通过调用 CreateType()),您也可以使用它来声明另一种类型的局部变量。

我遇到的另一个障碍是未完成的 TypeBuilder 上的 GetConstructor() 不起作用(它会抛出异常)。但是,如果您显式创建默认构造函数,则可以通过 ConstructorBuilder 调用它。

static void Main()
{
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("foo"), AssemblyBuilderAccess.RunAndSave);
var module = assemblyBuilder.DefineDynamicModule("foo.dll");
var aType = module.DefineType(
"A", TypeAttributes.Public | TypeAttributes.Class);
var bType = module.DefineType(
"B", TypeAttributes.Public | TypeAttributes.Class);
var aCtor = aType.DefineDefaultConstructor(MethodAttributes.Public);
var bCtor = bType.DefineDefaultConstructor(MethodAttributes.Public);
CreateMethodM(aType, bType, bCtor);
CreateMethodM(bType, aType, aCtor);
aType.CreateType();
bType.CreateType();
assemblyBuilder.Save("foo.dll");
}

static void CreateMethodM(
TypeBuilder thisType, Type otherType, ConstructorInfo otherCtor)
{
var method = thisType.DefineMethod(
"M", MethodAttributes.Private, typeof(void), Type.EmptyTypes);
var il = method.GetILGenerator();
var local = il.DeclareLocal(otherType);
il.Emit(OpCodes.Newobj, otherCtor);
il.Emit(OpCodes.Stloc, local);
il.Emit(OpCodes.Ret);
}

关于c# - ILGenerator.DeclareLocal() 采用尚未编译的类的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12432998/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com