[英]C#: What are virtual events and how can they be used?
虛擬活動如何運作? 你會如何覆蓋它? 這將如何運作? 在什么情況下你會這樣做?
例如,它可以替代受保護的 OnEvent 方法嗎? 那么繼承類可以覆蓋事件並直接引發它嗎? 或者那會是錯誤的還是行不通的?
MSDN 是這樣說的:
可以使用 virtual 關鍵字將事件標記為虛擬事件。 這使派生類能夠使用 override 關鍵字覆蓋事件行為。 覆蓋虛擬事件的事件也可以被密封,它指定對於派生類它不再是虛擬的。
但這並沒有讓我變得更聰明。 密封的東西很明顯。
注意:我已經看過C# 中的虛擬事件如何工作? 問題,但這並不是關於虛擬事件的工作原理。 而是那個人如何獲得他從使用它們中得到的結果。 試圖從他的例子和答案中找出虛擬事件是什么,但無法真正理解它。
虛擬事件只是一個可以在派生類中覆蓋的事件。
您對虛擬財產的概念感到滿意,可以覆蓋 getter 和 setter 嗎? 如果是這樣,您可以以完全相同的方式考慮虛擬事件:不是 getter 和 setter,而是“添加”操作和“刪除”操作。 這些可以是虛擬的,因此可以多態處理。 您可以像實現任何其他虛擬/覆蓋成員一樣實現它們。
例子:
using System;
class Base
{
public virtual event EventHandler Foo
{
add
{
Console.WriteLine("Base Foo.add called");
}
remove
{
Console.WriteLine("Base Foo.remove called");
}
}
}
class Derived : Base
{
public override event EventHandler Foo
{
add
{
Console.WriteLine("Derived Foo.add called");
}
remove
{
Console.WriteLine("Derived Foo.remove called");
}
}
}
class Test
{
static void Main()
{
Base x = new Derived();
x.Foo += (sender, args) => {};
}
}
請注意,事件本身不對引發時發生的事情負責 - 只是添加/刪除方面。 (無論如何,在 C# 中;CLR 本身有提升的概念,但我們暫時忽略它。)
如果您對事件和委托之間的區別有點模糊,您可能還想閱讀我關於事件的文章。
就個人而言,我發現我想要一個虛擬活動是非常罕見的。
另請注意,在 C# 中,派生類無法觸發純粹在基類中定義的事件(無論它具有什么修飾符)。 因此,我們需要為派生類創建一個新事件或覆蓋事件,並且在大多數情況下,如果要觸發相同的事件,則首選覆蓋事件。
對於要提出的Foo
,我發現已接受的答案中缺少 2 個替代方案。
public class Base
{
public virtual event EventHandler Foo;
public void Bar()
{
RaiseFoo();
}
protected virtual void RaiseFoo()
{
Foo?.Invoke(this, EventArgs.Empty);
}
}
public class Derived : Base
{
// In this case we use the base Foo as a backing store.
public override event EventHandler Foo
{
add { base.Foo += value; }
remove { base.Foo -= value; }
}
}
public class Derived2 : Base
{
public override event EventHandler Foo;
// In this case we raise the overriden Foo.
protected override void RaiseFoo()
{
Foo?.Invoke(this, EventArgs.Empty);
}
}
class Test
{
static void Main()
{
Base x = new Derived();
x.Foo += (sender, e) => { };
x.Bar();
Base x2 = new Derived2();
x2.Foo += (sender, e) => { };
x2.Bar();
}
}
請注意,這不起作用:
public class Derived3 : Base
{
public override event EventHandler Foo
{
add { base.Foo += value; }
remove { base.Foo -= value; }
}
protected override void RaiseFoo()
{
Foo?.Invoke(this, EventArgs.Empty);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.