您可以使虚拟 B 呼叫成为您选择的默认委托。以下将允许继承和覆盖:(实际上覆盖已经覆盖的:D)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class A
{
public delegate void delegateB();
public delegateB _B;
public A() {
_B = B;
}
public void Override(delegateB newB)
{
_B = newB;
}
public virtual void B()
{
if (_B != null && _B != this.B) {
Console.WriteLine("OVERRIDEN B IN A");
_B();
}
else {
Console.WriteLine("VIRTUAL B IN A");
}
}
}
class cB : A {
public override void B() {
if (base._B != null && base._B != this.B)
{
Console.WriteLine("OVERRIDEN B IN B");
_B();
}
else
{
Console.WriteLine("IN B");
}
}
}
class Program
{
class Overrider {
public void MyB()
{
Console.WriteLine("MyB");
}
}
public static void Main(string[] Args)
{
A a = new A();
a.B();
Overrider ovr = new Overrider();
a.Override(ovr.MyB);
a.B(); // Will print MyB
cB b = new cB();
b.B();
b.Override(ovr.MyB);
b.B();
}
}
}
输出:
VIRTUAL B IN A
OVERRIDEN B IN A
MyB
IN B
OVERRIDEN B IN B
MyB
您甚至可以调用base.B();
cB.B() ,这将有效地调用覆盖的委托,但会给出以下输出:
VIRTUAL B IN A
OVERRIDEN B IN A
MyB
IN B
OVERRIDEN B IN B
OVERRIDEN B IN A
MyB
我建议您采取一些类似的方法或设计模式方法,甚至不要考虑反射 Emit。您的代码将无法在高性能应用程序中使用。代表很快,反思很慢。