Hi Gábor and thanks for you help!! Sadly it did not quite work out.
The ctor.DeclaringType is a TypeDefinition and I can't assign the result of ctor.DeclaringType.MakeGenericInstanceType(genericArg) If I do ctor.DeclaringType.MakeGenericInstanceType(genericArg).Resolve it will turn my generic type into a TypeDefiniton with all its generic type information lost. In other words back to where I started. Any thoughts on this? Regards Bernhard Richter On May 8, 12:11 pm, Gábor Kozár <[email protected]> wrote: > Hi, > > I've had the same issue before, but I've managed to solve it with the help > of Jb. > > What you need to do is the following: > > TypeReference genericArg = _moduleDefinition.TypeSystem.Int32; > GenericInstanceType genericType = > _moduleDefinition.Import(typeof(Nullable<>)) > .MakeGenericInstanceType(genericArg); > MethodDefinition ctor = genericType.Resolve().Methods.First(m => > m.IsConstructor && m.Parameters.Count == 1); > > Note that if you try to emit a newobj instruction with 'ctor' with its > operand at this point, you'll get invalid IL, because when you use > Resolve(), you lose all generic argument information. We need to provide > that manually. > For that, you have to add your generic argument to ctor.DeclaringType, or > alternatively, you can use Rocks' MakeGenericInstanceType, like so: > > ctor.DeclaringType = ctor.DeclaringType.MakeGenericInstanceType(genericArg); > > Now you can emit your newobj instruction with 'ctor' being its argument. > Note that you _might_ need to clone ctor.DeclaringType first (I'm not sure, > I don't have my code in front of me atm), but you get the general idea. > > Hope this helps! > > 2011/5/8 seesharper <[email protected]> > > > > > > > > > Hi! > > > I don't understand how to emit the code to create an instance of a > > generic type. > > > Mono.Cecil 0.9.4.0 > > > I will illustrate this with a very simple example. > > > This is the code that I want to emit. > > > public void TestNull(int value) > > { > > Nullable<int> test = value; > > } > > > NOTE: > > > I don't know that the generic argument is an int at the time of > > emitting the code. > > > I need to read the parameter type and create a Nullable<T> according > > to the parameter type. > > > This means that I CAN'T do something like: > > > MethodReference ctor = _moduleDefinition.Import(typeof > > (Nullable<int>).GetConstructor(new Type[] {typeof (int)})); > > > This is the IL code that needs to be emitted. > > > .maxstack 2 > > .locals init ( > > [0] valuetype [mscorlib]System.Nullable`1<int32> test) > > L_0000: nop > > L_0001: ldloca.s test > > L_0003: ldarg.1 > > L_0004: call instance void > > [mscorlib]System.Nullable`1<int32>::.ctor(!0) > > L_0009: nop > > L_000a: ret > > > So this is what I got so far. > > > First a create a GenericInstanceType: > > > var nullableType = _moduleDefinition.Import(typeof(Nullable<>)); > > var genericType = > > > nullableType.MakeGenericInstanceType(_moduleDefinition.Import(typeof(int))) > > ; > > > (yeah, I used the Cecil.Rocks extension method for creating the > > generic instance type, but that is not the issue here.) > > > The int would be the type from the value parameter of the TestNull > > method. > > > Now I have a GenericInstanceType that represents Nullable<int>. > > > But how do I create a MethodReference that represents the constructor > > passed to OpCodes.NewObj? > > > The GenericInstanceType which is derived from MethodReference does not > > have a collection of methods so I can't get it from there either. > > > Next I tried something like this: > > > MethodReference constructorReference = new MethodReference(".ctor", > > _moduleDefinition.Import(typeof(void)), genericType); > > > No luck on this either. > > > A lot of forum posts suggests that the methodreference should be added > > to the MemberReferences collection of the module. > > > But that is a read-only collection available from the > > GetMemberReferences method. > > > I must be missing something? > > > Any help on this issue would be great!!! > > > Regards > > > Bernhard Richter > > > -- > > -- > > mono-cecil -- -- mono-cecil
