gpt4 book ai didi

c# - 在 C# 中动态覆盖任何方法

转载 作者:行者123 更新时间:2023-12-05 06:40:27 25 4
gpt4 key购买 nike

我正在努力实现这样的目标

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 个属性,Func 的 MethodInfo 和一个 Type[] GenericTypes,如果需要我也可以访问 Func 本身。

我认为对于字典中的每个方法,我都必须在我动态创建的类型中创建一个新方法,其中这个新方法主体只是关联 Func 的执行,但我似乎无法完成这项工作。

一些帮助将不胜感激,如果您认为我的方向有误,请告诉我。

注意:我不能使用其他框架或库,因为这是一个 friend 的作业,我发现这个问题很有趣,我正在努力帮助他。

Proxy 是我创建的一个类,它只使用 For 方法返回一个对象,您可以在其中调用 Override(此方法返回 this),然后当 Proxify 被调用时,它返回扩展 T 的内容。复制了所有值,但某些方法被重写,如代码所示。

最佳答案

如果 Player 的所有公共(public)成员都是虚拟的,您可以简单地派生一个包装类并将其用作代理的基类

假设 Player 有一个 ToString 和一个 Run 方法。然后删除

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();
}
}

现在你可以像这样创建一个具体的代理类

public class MyPlayerProxy : PlayerProxyBase
{
public MyPlayerProxy(Player player)
: base(player)
{ }

public override string ToString()
{
return _player.Name;
}
}

动态创建代理:

Player p = new MyPlayerProxy(lebron);

关于c# - 在 C# 中动态覆盖任何方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42599348/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com