[英]How to declare events inside a dictionary initialization?
我正在創建一個事件字典,我想在該字典的初始化中聲明這些事件,而不是在其他地方聲明它們並將鏈接放置到字典中。
static event EventDelegate Event1;
static event EventDelegate Event2;
static event EventDelegate Event3;
public enum EventTypes
{
Event1,
Event2,
Event3,
}
public static Dictionary<EventTypes, EventDelegate> events = new Dictionary<EventTypes, EventDelegate>
{
{EventTypes.Event1, Event1},
{EventTypes.Event2, Event2},
{EventTypes.Event3, Event3},
};
所以我想做這樣的事情:
{EventTypes.Event1, new event EventDelegate Event1}
那可能嗎?
包裝活動怎么樣?
class MyEventWrapper
{
public event EventDelegate Handlers;
public void Raise(object sender, EventArgs args)
{
Handlers?.Invoke(sender, args);
}
}
//
Dictionary<EventTypes, MyEventWrapper> eventMap = new Dictionary<EventTypes, MyEventWrapper>
{
{ EventTypes.Event1, new MyEventWrapper() },
{ EventTypes.Event2, new MyEventWrapper() },
};
//
eventMap[EventTypes.Event1].Handlers += (s, a) => { };
eventMap[EventTypes.Event2].Handlers += (s, a) => { };
//
eventMap[EventTypes.Event1].Raise(this, new EventArgs());
您可以使用EventDelegate
的簽名聲明一個空身體委托,並將其用於字典項的初始化。
public delegate void EventDelegate(object data);
public static readonly EventDelegate EventDelegateEmptyBody = (_) => { };
public static Dictionary<EventTypes, EventDelegate> Events = new Dictionary<EventTypes, EventDelegate>
{
{EventTypes.Event1, EventDelegateEmptyBody},
{EventTypes.Event2, EventDelegateEmptyBody},
{EventTypes.Event3, EventDelegateEmptyBody},
};
缺點是每次引發事件時都會調用此空方法,因此您將失去一些性能。 好處是,在調用委托之前,您無需檢查委托是否為空。 它永遠不會是空的。
您可以使用實際執行某些操作的方法,而不是使用空方法,例如記錄事件的引發。
示例代碼演示了Events
字典的用法:
Events[EventTypes.Event1] += (object data) =>
{
Console.WriteLine($"Event1 first handler: {data}");
};
Events[EventTypes.Event1] += (object data) =>
{
Console.WriteLine($"Event1 second handler: {data}");
};
Events[EventTypes.Event2] += (object data) =>
{
Console.WriteLine($"Event2 handler: {data}");
};
Events[EventTypes.Event1].Invoke("test1");
Events[EventTypes.Event2].Invoke("test2");
Events[EventTypes.Event3].Invoke("test3");
控制台輸出:
Event1 first handler: test1
Event1 second handler: test1
Event2 handler: test2
更新:似乎空身體代表是多余的。 可以使用空值初始化Events
字典,並且工作得很好。
public static Dictionary<EventTypes, EventDelegate> Events = new Dictionary<EventTypes, EventDelegate>
{
{EventTypes.Event1, null},
{EventTypes.Event2, null},
{EventTypes.Event3, null},
};
唯一的區別是我們必須在引發事件之前檢查null(null條件運算符使其變得容易)。
Events[EventTypes.Event1]?.Invoke("test1");
Events[EventTypes.Event2]?.Invoke("test2");
Events[EventTypes.Event3]?.Invoke("test3");
如果你這樣定義你的字典:
public delegate void EventDelegate(object data);
public static Dictionary<EventTypes, EventDelegate> Events =
new Dictionary<EventTypes, EventDelegate>
{
{ EventTypes.Event1, (EventDelegate)((_) => { }) },
{ EventTypes.Event2, (EventDelegate)((_) => { }) },
{ EventTypes.Event3, (EventDelegate)((_) => { }) },
};
public enum EventTypes
{
Event1,
Event2,
Event3,
}
那么這段代碼就是一種享受:
Events[EventTypes.Event1] += (object data) => Console.WriteLine($"Event1 (1): {data}");
Events[EventTypes.Event1] += (object data) => Console.WriteLine($"Event1 (2): {data}");
Events[EventTypes.Event2] += (object data) => Console.WriteLine($"Event2: {data}");
Events[EventTypes.Event1]("A");
Events[EventTypes.Event2]("B");
Events[EventTypes.Event3]("C");
我得到的輸出是:
Event1 (1): A Event1 (2): A Event2: B
然后,您可以在字典初始化中明確聲明這些事件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.