我正在尝试使用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);
那么,一个人如何创建尚未创建的另一种类型的常量?