How virtual events work in C#?(虚拟事件如何在 C# 中工作?)
问题描述
以下是我用于测试的程序.它打印(如预期):
Below is the program I used for the test. It prints (as expected):
Raise A
Event from A
Raise B
Event from B
现在,如果我们将 Main 的前两行更改为:
Now, if we change first two lines of the Main to be:
A a = new B();
B b = new B();
程序将打印:
Raise A
Raise B
Event from B
这也是意料之中的,因为覆盖事件隐藏了基类中的私有支持字段,因此基类触发的事件对派生类的客户端不可见.
which is also expected, as overriding event hides the private backing field in the base class and therefore events fired by the base class are not visible to clients of the derived class.
现在我将相同的行更改为:
Now I am changing the same lines to:
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的)实例,它具有以下字段:
We have a single instance (of B) which has the following fields:
- A.VirtualEvent: null
- B.VirtualEvent:两个事件处理程序
对 a.RaiseA()
的调用 只是 打印Raise A" - 仅此而已,因为 A 中的私有字段为空.
The call to a.RaiseA()
just prints "Raise A" - but nothing more, because the private field in A is null.
对 b.RaiseB()
的调用会打印剩余的三行,因为该事件已被订阅了两次(一次打印来自 A 的事件",一次打印来自 B 的事件").
The call to b.RaiseB()
prints the remaining three lines, because the event has been subscribed to twice (once to print "Event from A" and once to print "Event from B").
这有帮助吗?
为了更清楚 - 将虚拟事件视为一对虚拟方法.很像这样:
To make it clearer - think of the virtual event as a pair of virtual methods. It's very much like this:
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
}
现在更清楚了吗?这不是完全那样,因为据我所知,您不能只覆盖事件的部分"(即其中一种方法),但它给人的总体印象是正确的.
Now is it clearer? It's not quite like that because as far as I'm aware you can't override just "part" of an event (i.e. one of the methods) but it gives the right general impression.
这篇关于虚拟事件如何在 C# 中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:虚拟事件如何在 C# 中工作?
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 输入按键事件处理程序 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01