簡體   English   中英

如何在字典初始化中聲明事件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM