[英]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 的事件方法。
這是可以理解的,還是您更喜歡一些代碼? :)
正如許多人所指出的,將事件傳遞給方法要么是不可能的,要么並不簡單。
請澄清,但我懷疑您的預期用途將類似於:
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(也不會有幫助)。
如果注冊邏輯很復雜或者您必須保持 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.