On Mon, 20 Oct 2008 20:37:01 -0700, Navaneeth.K.N
<Na*********@discussions.microsoft.comwrote:
[...]
// need to clear the ProductChanged event handlers here
// I can't get the invocation list of "Product.ProductChanged" event
here.
is there anyway to achieve this? I think some kind of reflection can do
that, but I am not sure how to go about it.
Reflection would not be at all reliable. The field backing the event
could be modified with reflection, but the name of the field could change
at any time. Even if you could rely on the name, it's a _really_ bad idea
to go around mucking about the internals of some class. If you're not
allowed to modify the class itself to support what you want, then you
definitely have no business poking around the class's internals. That's
bad design and a maintenance nightmare.
Any help would be great
IMHO, the only correct way to do it is to keep your own list of all the
delegates you've subscribed to the event, so that when you want to remove
them all, you can do that.
One way to effectively accomplish this is to actually duplicate the event
yourself in your own class, subscribe a single event handler to the
Product class, and then forward the event to your own event. When you
want to clear your own event, you can just set it to null (from within the
class declaring the event, where you are actually setting the event's
delegate field to null).
In your case, however, it looks like you want to apply this to the same
event on multiple instances of the same type. So you'll need to combine
the above approach with a convenient way to map each instance to the
delegate used for the event. A Dictionary<instance can be used for that.
For example (error-checking removed for clarity, uncompiled code):
class MyClass
{
private Dictionary<Product, EventHandler_dictEventForwarder =
new Dictionary<Product, EventHandler>();
private void _Subscribe(Product product, EventHandler handler)
{
EventHandler handlerOld;
if (_dictEventForwarder.TryGetValue(product, out handlerOld))
{
handlerOld += handler;
}
else
{
handlerOld = handler;
product.ProductChanged += _ForwardingHandler;
}
_dictEventForwarder[product] = handlerOld;
}
private void _Unsubscribe(Product product, EventHandler handler)
{
EventHandler handlerNew = _dictEventHandler[product] - handler;
if (handlerNew == null)
{
_dictEventHandler.Remove(product);
product.ProductChanged -= _ForwardingHandler;
}
else
{
_dictEventHandler[product] = handlerNew;
}
}
private void _Clear(Product product)
{
_dictEventHandler.Remove(product);
product.ProductChanged -= _ForwardingHandler;
}
private void _ForwardingHandler(object sender, EventArgs e)
{
_dictEventForwarder[(Product)sender](sender, e);
}
}
You'll note that to subscribe/unsubscribe handlers to the event, you need
to go through the special methods for the purpose, rather than doing it
directly. They wind up subscribing/unsubscribing a single method that
looks up the appropriate delegate for each instance's event and invokes
that delegate when the instance's event is raised.
Hope that helps.
Pete