1
我正在创建一个动态方法来在运行时复制一个对象。让我们假设:Reflection.Emit - IL - 对象上的调用方法
class Source
{
public List<int> L1 {get;set;}
}
class Dest
{
public List<int> L1 {get;set;}
}
现在,这种情况正常工作。我得到Source.L1并设置了Dest.L1。我这样做与以下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);
所有这一切工作正常......现在来棘手的部分。让我们改变目的地到:
class Dest
{
private List<int> _l1 = new List<int>();
public List<int> L1 {get { return _l1; } }
}
现在我想在这种情况下,要做的就是调用Dest.L1.Clear(),然后Dest.L1.AddRange(...)。
我甚至无法使用.Clear工作。
我仍会有:
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);
如何做,我需要建立IL在TODO块?我试图做dup/loadArg0 /调用miGetter /调用miClear,但那给了我一个无效的程序。
你为什么要叫'Clear'?你不是在创造一个新的“Dest”吗?施工时这将是空的。 –
看到较低的Dest的第二个版本。 L1现在是一个只读集合,所以你不能给调用者打电话(好吧,你可以,但你不应该) – SledgeHammer
这不是我的问题。当你创建一个新的'Dest'时,'L1'列表是空的。你需要调用'AddRange',但是你不必先调用'Clear'。 –