我想创建一个调用特定实例方法的委托,遗憾的是,如果该方法是虚拟的,那么将调用继承类的方法的覆盖而不是基本版本。
public class Base{
public virtual void Method(){
Console.WriteLine("Base");
}
}
public class Child : Base{
public override void Method(){
Console.WriteLine("Child");
}
}
如果代码中的其他地方我有以下内容::
var action = Delegate.CreateDelegate(typeof(Action<Base>), typeof(Base).GetMethod("Method")) as Action<Base>;
action(new Child());
此程序的输出为Child
。我真的很喜欢Base
。我已经尝试了表达式树的相同的东西,我得到相同的结果,因为IL发出使用callvirt
方法。用Reflection.Emit
确实是这样做的唯一方法吗?
我问的原因是我使用类型构建器来覆盖类的行为。如果我自己编写方法,我可以去base.Method()
或其他什么,但是,某些方法行为只能在运行时动态确定,因为考虑到许多可能的情况会非常繁琐。
由于我在运行时创建了一个派生自Base
的类,如果我尝试在Method()
重载内部调用Method()
,我会使它导致无限递归和堆栈溢出异常。 (不太好)。
这是一个AOP样式项目,我在运行时向方法添加一些逻辑。我使用属性标记方法,然后我有一个类型构建器,使用CompileToMethod(methodbuilder)
http://msdn.microsoft.com/en-us/library/dd728224.aspx创建methodBuilders,为表达式树提供方法构建器的主体,
这比反射更简单。因为逻辑是非平凡的,我正在添加。我的目标是让工厂吐出一个新的类,每当我调用Method()
时,它会在最终调用基础实现之前先做一些逻辑。
答案 0 :(得分:1)
也许您可以使用这样的解决方法:
public class Base{
public virtual void Method(){
MethodImpl();
}
public void MethodImpl(){
Console.WriteLine("Base");
}
}
public class Child : Base{
public override void Method(){
Console.WriteLine("Child");
}
}
现在,您可以创建代表MethodImpl
的代理。
答案 1 :(得分:1)
是的,Reflection.Emit
是.NET框架提供的实现方法重载的唯一方法。由于在重载方法时不使用其他API,因此它们不提供链接到基本实现的任何方法。
答案 2 :(得分:0)
假设在这里发生了什么?
class Base { public abstract void Method(); }
class Child {
public override void Method() {
Console.WriteLine("Child.Method");
}
}
Action<Base> magicalAction = // defined somehow
magicalAction(new Child()); // aiya!
你试图打败虚拟方法的观点。为什么呢?
答案 3 :(得分:0)
由于Reflection.Emit
是构建整个方法的一种困难方法,我建议使用Reflection.Emit
创建私有方法,仅用于调用base
方法。然后,您可以从Expression
s。