c# - 虚拟事件如何在 C# 中工作?

标签 c# events compiler-construction

下面是我用来测试的程序。 它打印(如预期):

Raise A
Event from A
Raise B
Event from B

现在,如果我们将 Main 的前两行更改为:

        A a = new B();
        B b = new B();

程序将打印:

Raise A
Raise B
Event from B

这也是预期的,因为覆盖事件隐藏了基类中的私有(private)支持字段,因此基类触发的事件对派生类的客户端不可见。

现在我将相同的行更改为:

 B b = new B();
 A a = b;

然后程序开始打印:

Raise A
Raise B
Event from A
Event from B

这是怎么回事?

class A
{
    public virtual event EventHandler VirtualEvent;
    public void RaiseA()
    {
        Console.WriteLine("Raise A");
        if (VirtualEvent != null)
        {
            VirtualEvent(this, EventArgs.Empty);
        }
    }
}
class B : A
{
    public override event EventHandler VirtualEvent;
    public void RaiseB()
    {
        Console.WriteLine("Raise B");             
        if (VirtualEvent != null)
        {
            VirtualEvent(this, EventArgs.Empty);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();

        a.VirtualEvent += (s, e) => Console.WriteLine("Event from A");
        b.VirtualEvent += (s, e) => Console.WriteLine("Event from B");

        a.RaiseA();
        b.RaiseB();
    }
}

最佳答案

我们有一个(B 的)实例,它具有以下字段:

  • A.VirtualEvent: null
  • B.VirtualEvent:两个事件处理器

a.RaiseA() 的调用 只是 打印“Raise A” - 但仅此而已,因为 A 中的私有(private)字段为空。

调用 b.RaiseB() 打印剩余的三行,因为该事件已被订阅两次(一次打印“Event from A”,一次打印“Event from B” ).

这有帮助吗?

编辑:为了更清楚 - 将虚拟事件视为一对虚拟方法。它非常像这样:

public class A
{
    private EventHandler handlerA;

    public virtual void AddEventHandler(EventHandler handler)
    {
        handlerA += handler;
    }

    public virtual void RemoveEventHandler(EventHandler handler)
    {
        handlerA -= handler;
    }

    // RaiseA stuff
}

public class B : A
{
    private EventHandler handlerB;

    public override void AddEventHandler(EventHandler handler)
    {
        handlerB += handler;
    }

    public override void RemoveEventHandler(EventHandler handler)
    {
        handlerB -= handler;
    }

    // RaiseB stuff
}

现在更清楚了吗?它不是完全那样的,因为据我所知,您不能仅覆盖事件的“部分”(即其中一种方法),但它给出了正确的总体印象。

关于c# - 虚拟事件如何在 C# 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/714893/

相关文章:

compiler-construction - 没有 "compiled language"或 "interpreted language"这样的东西

c# - Microsoft Outlook 自动化 : Capturing a Save event

C# 相当于 Java 的 scn.nextInt( )

javascript - 带有 prototype.js 的类实例上的事件

python - 在 Python 中构建编译器 : determining integer values

php - 编译成 PHP 的编程语言?

c# - 绑定(bind)到 ViewModel 的子类属性

c# - 无法连接到任何指定的 MySQL 主机。 <添加名称 ="MySqlSiteMapProvider"

objective-c - 在 UIResponder 链上发送事件?

c# - 在 C# 中,事件处理程序参数是逆变的吗?