使用Reflection.Emit为嵌套的通用枚举const字段循环依赖关系生成代码

时间:2018-08-29 23:19:03

标签: c# reflection.emit

我正在尝试使用Reflection.Emit生成代码,该代码看起来类似于Roslyn为此生成的代码:

public class MyGeneric<T>
{
    public const MyGeneric2<T>.NestedEnum c1 = MyGeneric2<T>.NestedEnum.Value1;

    public enum NestedEnum
    {
        Value1,
        Value2,
    }
}

public class MyGeneric2<T>
{
    public const MyGeneric<T>.NestedEnum c2 = MyGeneric<T>.NestedEnum.Value2;

    public enum NestedEnum
    {
        Value1,
        Value2,
    }
}

在Reflection.Emit期间使用Enum类型的常量类字段进行的实验表明,必须先创建嵌套的通用枚举,然后才能使用它。但是,然后this example如何与Roslyn一起很好地编译?

这是我尝试使用嵌套泛型类型枚举的方法:

AssemblyName am = new AssemblyName();
am.Name = "TestAsm";
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(am, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule("testmod", "TestAsm.dll");

var gt = mb.DefineType("MyGeneric`1");
gt.DefineGenericParameters("T");

var gtne = gt.DefineNestedType("NestedEnum", TypeAttributes.NestedPublic | TypeAttributes.Sealed, typeof(Enum));
gtne.DefineGenericParameters("T");
gtne.DefineField("value__", typeof(int), FieldAttributes.Private | FieldAttributes.SpecialName);
gtne.DefineField("Value1", gtne, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
gtne.DefineField("Value2", gtne, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);

// First we need to create MyGeneric type before we can create NestedEnum
gt.CreateType();
var ct = gtne.CreateType(); // If we were to execute this before previous line, exception would be thrown

var mt = mb.DefineType("MyTest");

// Here we can safely use ct since it is created type.
mt.DefineField("sfield1", ct.MakeGenericType(typeof(int)), FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal).SetConstant(1);

// Next line fails since we must use fully created type and not type builder
mt.DefineField("sfield2", gtne.MakeGenericType(typeof(int)), FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal).SetConstant(1);

那么,一个人如何创建尚未创建的另一种类型的常量?

0 个答案:

没有答案