I’ve been commissioned with cleaning up memory leaks in our code as well as placing checks to prevent further leaks. I’ve noticed un-detached handlers seem to be the main cause. Most are straight forward, but there are a couple things in code that have made me scratch my head.
First:
myObject.someEvent -= null;
Am I correct in assuming that does absolutely nothing? (I know that if an event is local you can set it to null since it’s essentially a multicast delegate).
Second, for anonymous handlers:
myObject.someEvent += ()=> { x + y; };
myObject.someEvent -= ()=> { x + y; };
Am I correct in saying the second instruction is worthless as well since the anonymous methods will be compiled as two separate delegates and therefore the subtraction doesn’t actually point to the correct handler that would need to be removed? (For anyone looking for a proper solution to solve this, look here).
I don’t want to settle for “yeah, that’s right”, I want to know why these things don’t work (assuming my assertions are correct).
In the first case we can see from the decompiled implementation of
MulticastDelegate.CombineImpl(use IL Spy or something) that if the delegate passed in isnullthen no combining is done – so yes, removing a null delegate does nothing.In the second case it all depends on whether or not the compiler considers the two lambda expressions to be equal. This exact question is indirectly answered in this blog article
You can work out whether or not the current C# compiler considers these two to be equal or not fairly easily however thats not really the point – this is implementation defined behaviour and shouldn’t be relied on.