C# How to remove and cleanup all events
Ideally I want a function something like the following (this example doesn't compile):
void AddRemoveEvent<TEvent, TArgs>(TEvent e, EventHandler<TArgs> h, bool add)
where TArgs : System.EventArgs
{
if (add)
{
e += h;
}
else
{
e -= h;
}
}
Then I can write functions:
void AddRemoveEvents(bool add)
{
AddRemoveEvent(aMemberControl.Click, OnClick, add);
}
I then know I can call the function again to remove all handlers. I'm thinking this would be better than writing, keeping and relying on two functions being kept in sync:
void AddEvents(bool add)
{
aMemberControl.Click += OnClick;
}
void RemoveEvents(bool add)
{
aMemberControl.Click -= OnClick;
}
A colleague has written a handy class that does this kind of stuff that uses reflection. It's very useful, but it relies on the name of the event being passed in as a string. I'm looking for a type safe version. Has anybody got any ideas on if it's possible to write this?
Thanks.
I know I shouldn't really have to unwire stuff everywhere because the garbage collector should take care of most cases. But, sometimes a stray eve开发者_运维知识库nt causes a leak, and so I find it safer to just try and remove all events I add rather than trying to mess about with a profiler trying to identify the ones that do cause problems.
I've seen this related question:
How to remove all event handlers from a controlYou can't do this directly, unfortunately. There's no "event object" available directly in a safe way in C#. You could do it if you had the EventInfo
, but you'd have to get that by name. For example:
void AddRemoveEvent(object target, string name, Delegate handler, bool add)
where TArgs : System.EventArgs
{
EventInfo info = target.GetType().GetEvent(name);
// Error handling left as an exercise for the reader :)
if (add)
{
info.AddEventHandler(target, handler);
}
else
{
info.RemoveEventHandler(target, handler);
}
}
Not terribly nice :(
I'm not sure I'd bother with this single method, by the way - I'd just have separate AddEventHandler and RemoveEventHandler methods. Maybe have one common method to fetch the EventInfo, making sure it exists and is of the appropriate type etc - but not a Boolean to indicate add/remove.
With C# 3.5 magic strings can in a number of situations be replaced with expression trees. There are a number of examples floating around the need to pass a string to the PropertyChanged event of INotifyPropertyChanged. FluentNhibernate makes nice use of this feature to be able to express behaviour for the property of some type.
You may then be able to say something like Remove((MyControlType t) => t.Click
) . With the code from the other Stackoverflow post you probably get away without specifying the actual methods being the event handler.
精彩评论