当前位置:  开发笔记 > 编程语言 > 正文

虚拟事件如何在C#中运行?

如何解决《虚拟事件如何在C#中运行?》经验,为你挑选了1个好方法。

以下是我用于测试的程序.它打印(如预期):

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

这也是预期的,因为重写事件会隐藏基类中的私有支持字段,因此基类触发的事件对派生类的客户端不可见.

现在我将相同的行改为:

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

Jon Skeet.. 12

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

A.VirtualEvent:null

B.VirtualEvent:两个事件处理程序

调用a.RaiseA() 打印"提升A" - 但仅此而已,因为A中的私有字段为空.

b.RaiseB()打印剩余的三行的调用,因为事件已订阅两次(一次打印"来自A的事件",一次打印"来自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
}

现在更清楚了吗?它不是一样,因为据我所知,你不能覆盖只是一个事件的"部分"(即的方法之一),但它给出了正确的总体印象.



1> Jon Skeet..:

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

A.VirtualEvent:null

B.VirtualEvent:两个事件处理程序

调用a.RaiseA() 打印"提升A" - 但仅此而已,因为A中的私有字段为空.

b.RaiseB()打印剩余的三行的调用,因为事件已订阅两次(一次打印"来自A的事件",一次打印"来自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
}

现在更清楚了吗?它不是一样,因为据我所知,你不能覆盖只是一个事件的"部分"(即的方法之一),但它给出了正确的总体印象.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有