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

Reply via email to