开发者

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

I've got a strat开发者_如何学JAVAegy 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


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();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜