委托(delegate) 與 事件(event) 🔥
前言🙏
在之前的文章里介紹了C#中的委托(delegate)
(Action、Func、Predicate)的基本含義及用法
那本篇文章在這里還要介紹一個跟委托有很大關系的小伙伴——C#中的 事件(event)🎅
事件跟委托是有很大聯系的,所以也就導致很容易分不清他們兩個,以及什么時候用這兩個
上面有博客提到委托,想單獨了解委托的可以去看一下,本篇文章主要說一下 什么是事件 🎄
以及 事件與委托的區別🎁
委托和事件的定義 💬
委托
在這里再說一遍委托跟事件的簡單定義(沒有搜到特別準確的,都是大概定義,理解萬歲)
委托:delegate 是一種可用于封裝命名或匿名方法的參考型別, 委托類似于 C++ 中的函式指標;但是,委托是型別安全和可靠的,
委托是一種動態呼叫方法的型別,屬于參考型,
委托是對方法的抽象和封裝,委托物件實質上代表了方法的參考(即記憶體地址)
委托允許將方法作為引數進行傳遞,
委托可用于定義回呼方法,
委托可以把多個方法鏈接在一起,這樣,在事件觸發時可同時啟動多個事件處理程式,
委托簽名不需要與方法精確匹配,
事件
事件:事件是特殊型別的多路廣播委托,僅可從宣告它們的類或結構(發行者類)中呼叫,
如果其他類或結構訂閱了該事件,則當發行者類引發該事件時,會呼叫其事件處理程式方法,
事件表示C#中已定義的一個物件,即處理通知程序的物件
通常,每個事件的發生都會產生發送方和接收方,在.net框架中,事件是將事件發送者(觸發事件的物件)與事件接受者(處理事件的方法)相關聯的一種代理類,即事件機制是通過代理類來實作的,當一個事件被觸發時,由該事件的代理來通知(呼叫)處理該事件的相應方法
委托和事件的區別
簡單說了一下兩者的定義,眼神好的小伙伴這時候就會發現,事件的說明里有提到一句話:“事件也可以算一種特殊的委托”,這句話不是特別準確,但是也不妨可以這樣理解,
正因為如此,所以要我們先了解了 委托 再來看 事件 ,容易混淆大家的地方大多在于這兩者之間的區別,下面說一下委托和事件之間的區別:
委托和事件的區別如下:
| 區別 | 委托 | 事件 | |
|---|---|---|---|
| 1 | 是否是一個型別 | 是 | 否,事件修飾的是一個物件 |
| 2 | 是否可以在類外部進行呼叫 | 是 | 否 |
| 3 | 是否可以使用=來賦值 | 是 | 否 |
舉例說明
我們將創建兩個類ClassA和ClassB,這兩個類都很簡單,只有一個方法,并且這兩個類的方法簽名一樣,ClassC內有委托和事件,為了演示方便,我們將委托和事件的訪問權限都設為public,下面我們將主要看看委托和事件在使用上面的區別,
Class1
public class Class1
{
//宣告委托
public delegate void NumberChanger(int n);
//宣告事件
public static event NumberChanger changer;
public static void test()
{
changer(100);
}
static void Main(string[] args)
{
Class1.changer += Class2.ClassA_Test;
Class1.changer += Class3.ClassA_Test;
Class1.test();
}
}
Class2
class Class2
{
public static void ClassA_Test(int i)
{
Console.WriteLine("Class2:"+i);
}
}
Class3
class Class3
{
public static void ClassA_Test(int i)
{
Console.WriteLine("Class3:"+i);
}
}
區別一:是否是一個型別
class Class3
{
static void Main(string[] args)
{
//委托正確使用
Class1.NumberChanger n1 = Class2.ClassA_Test;
//事件使用 編譯器報錯
Class1.changer handle2 = Class2.ClassA_Test;
}
錯誤:Class1.changer 是“欄位”,但此處被當做“型別”來使用
區別二:委托可以在宣告它的類外部進行呼叫,而事件只能在類的內部進行呼叫,
(1)在類外部呼叫委托

(2)在類外部呼叫事件

事件“ClassC.Say_EventHandler”只能出現在 += 或 -= 的左邊(從型別“ClassC”中使用時除外)
區別三:委托可以在外部類使用 = 來賦值,事件只能在內部類用 = 賦值,外部類不可以

從編譯器提示的錯誤,我們可以了解到,事件只能在宣告它的類內部被呼叫,從事件本身來講,事件一般用于類自身的屬性變化時,用來通知外界自身的變化的,我們將對ClassC內部的一個屬性賦值,然后呼叫事件,模擬對外通知,代碼如下所示

總結 🏠
事件的使用方式跟委托沒什么區別,事件就相當于一個加了"event"修飾符的委托,在加了這個修飾以后,委托的部分功能就相當于被閹割了,通過這個加了修飾符以后,我們可以更好的控制注冊和注銷,對于一個外部類來說,它就只能通過"+=/-="注冊自己和注銷自己,而且外界也不能主動觸發一個事件,
委托一般用于回呼,而事件用于外部介面,例如在觀察者模式中,在被觀察者中可以宣告一個事件作為外部觀察者注冊的介面,
同時,這個事件只能在被觀察者內部觸發,而觀察者中無法觸發該事件,從而保證了安全性,
說了這么多,總結起來就一句話:事件與委托最主要的區別應該是不能在外部呼叫,但可以通過+=或-=進行注冊,但如果委托變數為私有,則外部不能注冊;如果為公有,則外部有可以呼叫,破壞了封裝,所以沒辦法,在這種情況就定義一個event就好了
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/279622.html
標籤:其他
