jeudi 7 avril 2016

Reflection.Emit - IL - call method on object

I'm working on creating a dynamic method at runtime to copy an object. Lets assume:

class Source
{
   public List<int> L1 {get;set;}
}

class Dest
{
   public List<int> L1 {get;set;}
}

Now, this situation works correctly. I get Source.L1 and I set Dest.L1. I do so with the following IL:

        generator.Emit(OpCodes.Newobj, constructor);
        generator.Emit(OpCodes.Dup);
        generator.Emit(OpCodes.Ldarg_0);
        generator.Emit(OpCodes.Callvirt, miGetter);
        generator.Emit(OpCodes.Callvirt, miSetter);
        generator.Emit(OpCodes.Ret);

All this is working fine... now comes the tricky part. Lets change Dest to:

class Dest
{
   private List<int> _l1 = new List<int>();
   public List<int> L1 {get { return _l1; } }
}

Now what I want to do in this case is call Dest.L1.Clear() and then Dest.L1.AddRange(...).

I can't even get the .Clear to work.

I still will have:

        generator.Emit(OpCodes.Newobj, constructor);

        // this block is repeated 5 times for various properties

        generator.Emit(OpCodes.Dup);
        generator.Emit(OpCodes.Ldarg_0);
        generator.Emit(OpCodes.Callvirt, miGetter);
        generator.Emit(OpCodes.Callvirt, miSetter);

        // List property will be copied here
        // miGetter = Dest.L1.Get
        // TODO
        // end list property

        generator.Emit(OpCodes.Ret);

How do I need to set up the IL in the TODO block? I tried doing dup/loadArg0/call miGetter/call miClear, but that gave me an invalid program.





Aucun commentaire:

Enregistrer un commentaire