這篇文章主要介紹了.NET/C#使用反射注冊事件的案例,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
不使用反射
例如,我們希望反射的類型是這樣的:
public class Walterlv
{
public event EventHandler BlogPublished;
}那么只需要使用如下代碼即可完成事件的注冊:
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);
當然,實際使用的時候,如果能訪問到 Walterlv 類型,當然也不會去用到反射,所以通常情況是這樣的:
public void AddHandler<T>(T instance, string eventName, EventHandler handler)
{
var eventInfo = instance.GetType().GetEvent(eventName);
eventInfo.AddEventHandler(instance, handler);
}安全地使用反射
雖然以上方式使用了反射成功注冊了事件,但實際上我們的參數中傳入了一個特定類型的委托 EventHandler。實際上事件的委托種類非常多。
在委托中,即便簽名完全相同,也不是同一個委托類型。如果傳入的參數類型改為 EventHandler<EventArgs> ,或者 BlogPublished 事件的類型改為 EventHandler<EventHandler>,雖然實際上這兩個委托的簽名是兼容的,但其委托類型不同,依然是不能互相轉換的。你會在運行時遇到一下異常:

▲ 委托無法轉換
所以我們必須有一些更安全的方式來注冊事件。
正常情況下,我們轉換一個簽名兼容的委托是使用構造函數:
public EventHandler ConvertDelegate(EventHandler<EventArgs> handler)
{
return new EventHandler(handler);
}那么在反射中,我們需要使用 Delegate.CreateDelegate 創建指定類型的委托。
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 的作用就是執行委托類型的轉換。我在 .NET Core/Framework 創建委托以大幅度提高反射調用的性能 中也提到過這個方法。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“.NET/C#使用反射注冊事件的案例”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。