溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

.NET/C#使用反射注冊(cè)事件的案例

發(fā)布時(shí)間:2021-02-07 14:03:39 來源:億速云 閱讀:162 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了.NET/C#使用反射注冊(cè)事件的案例,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

不使用反射

例如,我們希望反射的類型是這樣的:

public class Walterlv
{
 public event EventHandler BlogPublished;
}

那么只需要使用如下代碼即可完成事件的注冊(cè):

var walterlv = new Walterlv();
walterlv += Walterlv_BlogPublished;
public void Walterlv_BlogPublished(object sender, EventHandler handler)
{
}

使用反射

而如果使用反射,則是:

var walterlv = new Walterlv();
var eventInfo = typeof(Walterlv).GetEvent(nameof(BlogPublished));
var handler = new EventHandler(Walterlv_BlogPublished);
eventInfo.AddEventHandler(walterlv, handler);

當(dāng)然,實(shí)際使用的時(shí)候,如果能訪問到 Walterlv 類型,當(dāng)然也不會(huì)去用到反射,所以通常情況是這樣的:

public void AddHandler<T>(T instance, string eventName, EventHandler handler)
{
 var eventInfo = instance.GetType().GetEvent(eventName);
 eventInfo.AddEventHandler(instance, handler);
}

安全地使用反射

雖然以上方式使用了反射成功注冊(cè)了事件,但實(shí)際上我們的參數(shù)中傳入了一個(gè)特定類型的委托 EventHandler。實(shí)際上事件的委托種類非常多。

在委托中,即便簽名完全相同,也不是同一個(gè)委托類型。如果傳入的參數(shù)類型改為 EventHandler<EventArgs> ,或者 BlogPublished 事件的類型改為 EventHandler<EventHandler>,雖然實(shí)際上這兩個(gè)委托的簽名是兼容的,但其委托類型不同,依然是不能互相轉(zhuǎn)換的。你會(huì)在運(yùn)行時(shí)遇到一下異常:

.NET/C#使用反射注冊(cè)事件的案例
▲ 委托無法轉(zhuǎn)換

所以我們必須有一些更安全的方式來注冊(cè)事件。

正常情況下,我們轉(zhuǎn)換一個(gè)簽名兼容的委托是使用構(gòu)造函數(shù):

public EventHandler ConvertDelegate(EventHandler<EventArgs> handler)
{
 return new EventHandler(handler);
}

那么在反射中,我們需要使用 Delegate.CreateDelegate 創(chuàng)建指定類型的委托。

public void AddHandler<T>(T instance, string eventName)
{
 var eventInfo = instance.GetType().GetEvent(eventName);
 var methodInfo = GetType().GetMethod(nameof(Walterlv_BlogPublished));
 var @delegate = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo);
 eventInfo.AddEventHandler(instance, @delegate);
}

public void Walterlv_BlogPublished(object sender, EventHandler handler)
{
}

這里,Delegate.CreateDelegate 的作用就是執(zhí)行委托類型的轉(zhuǎn)換。我在 .NET Core/Framework 創(chuàng)建委托以大幅度提高反射調(diào)用的性能 中也提到過這個(gè)方法。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“.NET/C#使用反射注冊(cè)事件的案例”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI