using ILGenerator.Emit() to create a call to a method of an array type  
Author Message
Laurin





PostPosted: .NET Base Class Library, using ILGenerator.Emit() to create a call to a method of an array type Top

Hi there!

I have the following problem:

I create MSIL code using the ILGenerator class. The code to be created contains a call to a constructor or method of an array type. Sample:

class C1

{

public C1()

{

} // C1()

public void foo()

{

C2[,] c2 = new C2[3, 4];

} // foo()

} // class C1

class C2

{

public C2()

{

} // C2

public void foo()

{

C1[,] c1 = new C1[2, 3];

} // foo()

} // class C2()

As you can see in the output of ildasm C1::foo() contains this code:

.method public hidebysig instance void foo() cil managed

{

// Code size 10 (0xa)

.maxstack 2

.locals init ([0] class MyTest.C2[0...,0...] c2)

IL_0000: nop

IL_0001: ldc.i4.3

IL_0002: ldc.i4.4

IL_0003: newobj instance void class MyTest.C2[0...,0...]::.ctor(int32,

int32)

IL_0008: stloc.0

IL_0009: ret

} // end of method C1::foo

Now I want to create the same code using ILGenerator. When using the ILGenerator.Emit() method to create the newobj instruction, I'm supposed to pass a ConstructorInfo object. Normally I'd call

ConstructorInfo ci = typeof(MyTest.C2).MakeArrayType(2).GetConstructor(new Type[2] {typeof(int32), typeof(int32)});

but as C2 isn't created yet I get a NotSupportedException ("Not supported in a non-reflected type."). But I can't create C2 because it relies on C1.

Question: How can I get the ConstructorInfo object to create the newobj instruction

Note: There is no way to change the original code and it's not allways a newobj instruction but sometimes a 'call'.

Best regards

Laurin

P.S.: Sorry for the strange format, I couldn't get it looking the way I wanted it to.



.NET Development26  
 
 
Laurin





PostPosted: .NET Base Class Library, using ILGenerator.Emit() to create a call to a method of an array type Top

For those who run into the same problem: I solved it using ModuleBuilder::GetArrayMethod(). This method returns a MethodInfo object which can be used in ILGenerator::Emit().

Regards
Laurin