簡體   English   中英

如何將事件傳遞給 C# 中的 function?

[英]How can I pass an event to a function in C#?

我希望將事件傳遞給助手 function。 此 function 將向事件附加一個方法。 但是,我無法正確通過該活動。 我試過傳遞一個EventHandler<TEventArgs> 它可以編譯,但未附加事件(但仍會添加;似乎制作了事件處理程序的副本)。

例如,如果我有這個:

public event EventHandler<EventArgs> MyEvent;

和助手 function:

public static void MyHelperFunction<TEventArgs>(EventHandler<TEventArgs> eventToAttachTo)
{
    eventToAttachTo += (sender, e) => { Console.WriteLine("Hello world"); };
}

和來電者:

MyHelperFunction(MyEvent);
MyEvent(null, new EventArgs()); // Does nothing.

這不起作用的原因是 += 當應用於委托時會創建一個新委托,它是舊委托和新委托的組合。 它不會修改現有的委托。

為了使它起作用,您必須通過引用傳遞委托。

public static void Helper(ref EventHandler<EventArgs> e)
{
    e+= (x,y) => {};
}

這在方法之外起作用的原因是因為 LHS 仍然是實際字段。 所以 += 將創建一個新的委托並分配回成員字段。

剛剛想出了這個小幫手。 如果它是您自己創建的事件,您可以使用這樣的包裝器。 您可以像往常一樣使用 += 運算符附加處理程序,但可以傳遞包裝器,甚至可以從其他地方引發事件。

public class GenericEvent<T> where T:EventArgs
{
    public event EventHandler<T> Source = delegate { };

    public void Raise(object sender, T arg = default(T))
    {
        Source(sender, arg);
    }

    public void Raise(T arg = default(T))
    {
        Source(this, arg);
    }

    public void AddHandler(EventHandler<T> handler)
    {
        Source += handler;
    }

    public void RemoveHandler(EventHandler<T> handler)
    {
        Source -= handler;
    }

    public static GenericEvent<T> operator +(GenericEvent<T> genericEvent, EventHandler<T> handler)
    {
        genericEvent.AddHandler(handler);
        return genericEvent;
    }
}

創建事件,如:

public GenericEvent<EventArgs> MyEvent = new GenericEvent<EventArgs>();

附加處理程序:

MyEvent += (s,e) => {};

提升事件:

MyEvent.Raise();

只是猜測:您是否嘗試過將其作為參考傳遞?

public static void MyHelperFunction<TEventArgs>(ref EventHandler<TEventArgs> eventToAttachTo)

MyHelperFunction(ref MyEvent);

這不是很好,但你可以使用反射來做到這一點。

    public EventMonitor(object eventObject, string eventName)
    {
        _eventObject = eventObject;
        _waitEvent = eventObject.GetType().GetEvent(eventName);

        _handler = new EventHandler(SetEvent);
        _waitEvent.AddEventHandler(eventObject, _handler);
    }

其中 eventObject 是包含事件的 object,eventName 是事件的名稱。 SetEvent 是您的事件處理程序。

我也有這樣的處理方法:

    public void Dispose()
    {
        _waitEvent.RemoveEventHandler(_eventObject, _handler);
    }

傳遞類似 Action e = e => myevent += e; 並使用處理程序從方法調用? 它具有與 .NET 類一起使用的好處。

我有一個解決方案,我有兩個接口。 第一個接口具有綁定某些事件的方法,而另一個接口具有可以綁定到這些事件的事件方法。

第一個接口的綁定方法將第二個接口作為參數,這使得可以將事件綁定到任何實現第二個接口的 class 的事件方法。

這是可以理解的,還是您更喜歡一些代碼? :)

正如許多人所指出的,將事件傳遞給方法要么是不可能的,要么並不簡單。

  1. 請澄清,但我懷疑您的預期用途將類似於:

     void Register() { var super = new SuperHandler(); //not valid syntax: super.HandleEvent(MyEvent1); super.HandleEvent(MyEvent2); super.HandleEvent(MyEvent3); super.HandleEvent(MyEvent4); }

    您可以簡單地通過使您的預期通用事件處理程序可公開訪問(或在內部,如果您願意)來實現:

     public static class GenericHandler { public static void HandleAnyEvent(object sender, EventArgs e) { //handle } } public class SomeClass { void RegisterEvents() { var r = new EventRaiser(); r.ImportantThingHappened += GenericHandler.HandleAnyEvent; } }

    在此示例中,我的包羅萬象的處理程序位於 static class 中,但您也可以使用非靜態 class。 另外,我看到在您的示例中,您已將方法設為通用(TEventArgs)。 因為所有 EventHandler 派生類(例如 CancelEventHandler)都與基本 EventHandler 匹配,所以您不需要涉及 generics(也不會有幫助)。

  2. 如果注冊邏輯很復雜或者您必須保持 EventHandler 私有,請考慮使用接口事件 這可能無法滿足您減少代碼量的預期目標,但它將允許您創建一個 class 可以預測地處理特定類型的所有事件。

     interface IRaiseEvents { event EventHandler ConnectionCreated; event EventHandler ConnectionLost; } public class SuperHandler { void RegisterEvents(IRaiseEvents raiser) { raiser.ConnectionCreated += (sender, args) => Console.WriteLine("Connected."); raiser.ConnectionLost += (sender, args) => Console.WriteLine("Disconnected."); } }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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