I'm attempting to write a .NET compiler using System.Reflection.Emit how do I do type resolution?

社会主义新天地 提交于 2019-12-07 15:53:55

问题


I've got a strategy for resolving types from referenced dlls. I'm stuck on trying to resolve types that are defined in the assembly that is being compiled. I'm using the System.Reflection.Emit apis with no 3rd party libraries.

For instance:

class A {}
class B
{
    public A AnInstanceOfA {get; private set;}
}

What's the best way to resolve B's reference of A?

What about this:

class A
{
    B AnInstanceOfB {get; set;}
}
class B
{
    A AnInstanceOfA {get; set;}
}

where the classes contain instances of each other.

Is there a best practice way to do this? Any design patterns I should implement? I would prefer to use only the System.Reflection.Emit librarys but if there is a better way to do this or this can't be done with them, then using other library(s) is acceptable.

Thanks


回答1:


Could you elaborate on the issue that you're running into (perhaps showing code a small example of code that isn't working for you)? Because TypeBuilder derives from Type, if you're trying to define mutually recursive types you can pass the two TypeBuilders wherever you'd like to refer to the types.

EDIT

There's no need to "resolve" the types. You have access to the TypeBuilders for each and can use them just as if they were fully defined types. Here's an example that generates the code you requested in your update:

private void DefineAutoProp(string name, Type t, TypeBuilder tb)
{
    var fldName = name.Substring(0, 1).ToLower() + name.Substring(1);
    var fld = tb.DefineField(fldName, t, FieldAttributes.Private);
    var prop = tb.DefineProperty(name, PropertyAttributes.None, t, null);
    var getter = tb.DefineMethod("get_" + name, MethodAttributes.Public, t, null);
    var ilg = getter.GetILGenerator();
    ilg.Emit(OpCodes.Ldarg_0);
    ilg.Emit(OpCodes.Ldfld, fld);
    ilg.Emit(OpCodes.Ret);
    var setter = tb.DefineMethod("set_" + name, MethodAttributes.Public, typeof(void), new[] { t });
    ilg = setter.GetILGenerator();
    ilg.Emit(OpCodes.Ldarg_0);
    ilg.Emit(OpCodes.Ldarg_1);
    ilg.Emit(OpCodes.Stfld, fld);
    ilg.Emit(OpCodes.Ret);
    prop.SetGetMethod(getter);
    prop.SetSetMethod(setter);
}

public void DefineTypes()
{
    var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("test"), AssemblyBuilderAccess.Run);
    var mb = ab.DefineDynamicModule("test");
    var A = mb.DefineType("A", TypeAttributes.Public | TypeAttributes.Class);
    var B = mb.DefineType("B", TypeAttributes.Public | TypeAttributes.Class);
    DefineAutoProp("AnInstanceOfA", A, B);
    DefineAutoProp("AnInstanceOfB", B, A);
    A.CreateType();
    B.CreateType();
}


来源:https://stackoverflow.com/questions/2230440/im-attempting-to-write-a-net-compiler-using-system-reflection-emit-how-do-i-do

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!