none
Calling List<T>.AddRange(IEnumerable<T>) where T is an unfinished type in Reflection.Emit RRS feed

  • Question

  • I have problems trying to call the AddRange method for a List of an unfinished type (TypeBuilder)
    here is the code:

    1             AppDomain myDomain = AppDomain.CurrentDomain;  
    2             AssemblyName myAsmName = new AssemblyName("MyTest");  
    3             AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(myAsmName,  
    4                   AssemblyBuilderAccess.RunAndSave);  
    5  
    6             // An assembly is made up of executable modules. For a single-  
    7             // module assembly, the module name and file name are the same   
    8             // as the assembly name.   
    9             //  
    10             ModuleBuilder myModule =  
    11                 myAssembly.DefineDynamicModule(myAsmName.Name,  
    12                 myAsmName.Name + ".dll");  
    13  
    14             //define the class "myClass"  
    15             TypeBuilder myClass = myModule.DefineType("myClass", TypeAttributes.Public);  
    16  
    17             // define the stringField for myClass just for fun and add a member to myClass  
    18             FieldBuilder stringField = myClass.DefineField("myClassField"typeof(string), FieldAttributes.Public);  
    19  
    20             // define the class "Sample"  
    21             TypeBuilder myType = myModule.DefineType("Sample", TypeAttributes.Public);  
    22  
    23             //define list generics and ienumerable generic  
    24             Type genLstType = typeof(List<>).MakeGenericType(myClass);  
    25             Type rangeType = typeof(IEnumerable<>).MakeGenericType(myClass);  
    26  
    27             var method = genLstType.GetMethod("AddRange",  
    28                 BindingFlags.Instance | BindingFlags.Public,  
    29                 nullnew Type[] { rangeType }, null);  
    30  
    31             // define the field "list" of type List<myClass>  
    32             FieldBuilder fldBuilder = myType.DefineField("list", genLstType, FieldAttributes.Private);  
    33               
    34             //define properties to set the fields  
    35             PropertyBuilder listProperty = myType.DefineProperty("List", PropertyAttributes.None, genLstType, null);  
    36  
    37             // define set method for the property  
    38             MethodBuilder setListProperty = myType.DefineMethod("set_List",  
    39                 MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName,   
    40                 typeof(void),   
    41                 new Type[] { genLstType });  
    42  
    43             ILGenerator ilgen = setListProperty.GetILGenerator();  
    44  
    45             //just to make it simple lets call AddRange of the field  
    46  
    47             ilgen.Emit(OpCodes.Nop);  
    48             ilgen.Emit(OpCodes.Ldarg_0);  
    49             ilgen.Emit(OpCodes.Ldfld, fldBuilder);  
    50             ilgen.Emit(OpCodes.Ldarg_1);  
    51             ilgen.Emit(OpCodes.Callvirt, method);  
    52             ilgen.Emit(OpCodes.Ret);  
    53  
    54             myClass.CreateType();  
    55             myType.CreateType();  
    56  
    57             myAssembly.Save(myAsmName.Name + ".dll"); 

    If you run this code you will get an exceptio on the method defined in line 27, because myClass is an unfinished type.
    I have still not called myClass.CreateType() and I can't call it because I still need to add member to myClass and they cannot be added before this. 

    Is interesting also to note that for line 51 using IL DASM if I code this without Refelction.Emit the parameter type for the method AddRange is defined IEnumerable<!0> instead of IEnumerable<myClass>

    Please point me in the right direction or show me some code that solves this problem.

    I would really appreciate any help
    Wednesday, November 12, 2008 6:15 AM