我正在努力实现这样的目标
Player lebron = new Player("LeBron", 23, 2.03f);
lebron.Rings = 3;
lebron.Team = "Cleveland";
Player p = Proxy.For<Player>().Override("ToString", (target, argz) =>
{
return target.name;
}).Proxify(lebron);
其中Override的第一个参数给出的任何方法都可以替换为Func<T, object[], object // where T is the same type use in For, in this case Player
// and target is the T object (Player lebron in this case) and argz is the array of possible parameters
我想出这样做的方法是使用一个字典,方法名称为Key,并存储相应的Func<T, object[], object
。
使用Proxify,我将返回一个动态创建的新类型,扩展基类型T
并将原始对象中的每个属性或字段复制到此新动态创建的类型。这个目前正在运作。
问题:如何覆盖用Override
中给出的名称指定的任何函数,并且它的执行应该是给定的Func<T, object[], object>
处理程序?
我试过了
foreach(MethodInfo mi in cloneType.GetMethods(FLAGS))
{
if (overr.ContainsKey(mi.Name)){
Ops op;
if(! overr.TryGetValue(mi.Name, out op)) continue;
//tb.DefineMethodOverride(op.MethodInfo, mi);
MethodBuilder mb = tb.DefineMethod(mi.Name,
MethodAttributes.Public
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.Virtual
| MethodAttributes.Final,
CallingConventions.HasThis,
mi.ReturnType, op.GenericTypes);
ILGenerator il = mb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
}
}
Ops op只是Func的包装器,它存储2个properyies,Func的MethodInfo和一个Type [],如果需要的话,我也可以访问Func本身。
我认为对于字典中的每个方法,我必须在我动态创建的类型中创建一个新方法,其中这个新方法体只是执行相关的Func,但我似乎无法使其工作。< / p>
一些帮助将不胜感激,如果您认为我的方向错误,请告诉我。
注意:我不能使用其他框架或图书馆,因为这是一个朋友的分配,我发现这个问题很有趣,我试图帮助他。
Proxy是一个我只用For方法创建的类,它返回一个可以调用Override的对象(此方法返回this
)然后当调用Proxify时返回扩展T
的内容复制了所有值,但有些方法像代码所说的那样重写。
答案 0 :(得分:0)
如果Player
的所有公共成员都是虚拟成员,您可以简单地派生一个包装类并将其用作代理的基类
我们假设Player
有ToString
和Run
方法。然后delcare
public abstract class PlayerProxyBase : Player
{
protected readonly Player _player;
public PlayerProxyBase(Player player)
{
_player = player;
}
public override void Run()
{
_player.Run();
}
public override string ToString()
{
return _player.ToString();
}
}
现在您可以像这样创建一个具体的Proxy类
public class MyPlayerProxy : PlayerProxyBase
{
public MyPlayerProxy(Player player)
: base(player)
{ }
public override string ToString()
{
return _player.Name;
}
}
动态创建代理:
Player p = new MyPlayerProxy(lebron);