"Delegate subtraction has unpredictable result" in ReSharper/C#?
When using myDelegate -= eventHandler
ReSharper (version 6) issues:
Delegate subtraction has unpredictable result
The rational behind this is explained by JetBrains here. The explanation makes sense and, after reading it, I'm doubting all my uses of -
on delegates.
How then,
- can I write a non-auto event without making ReSharper grumpy?
- or, is there a better and/or "correct" way to implement this?
- or, can I just ignore ReSharper?
Here is simplified code:
public delegate void MyHandler (object sender);
MyHandler _myEvent;
public event MyHandler MyEvent
{
add
{
_myEvent += value;
DoSomethingElse();
}
remove
{
_myEvent -= value; // <-- ReSharper warning here
}
}
Solution 1:
Don't be afraid! The first part of ReSharper's warning only applies to removing lists of delegates. In your code, you're always removing a single delegate. The second part talks about ordering of delegates after a duplicate delegate was removed. An event doesn't guarantee an order of execution for its subscribers, so it doesn't really affect you either.
Since the above mechanics can lead to unpredictable results, ReSharper issues a warning whenever it encounters a delegate subtraction operator.
ReSharper is issuing this warning because multicast delegate subtraction can have gotchas, it isn't condemning that language feature entirely. Luckily those gotchas are in fringe cases and you are unlikely to encounter them if you're just instrumenting simple events. There is no better way to implement your own add
/remove
handlers, you just gotta take notice.
I'd suggest downgrading ReSharper's warning level for that message to "Hint" so that you don't get desensitized to their warnings, which are usually useful.
Solution 2:
You should not directly use delegates to sum or subtract. Instead your field
MyHandler _myEvent;
Should be instead declared as an event as well. This will solve the problem without risking your solution and still have the benefit of event usage.
event MyHandler _myEvent;
Usage of delegate sum or subtract is dangerous because you can lose events when simply assigning the delegate (as per declaration, the developer will not directly infer this is a Multicast delegate as when it is declared as an event). Just to exemplify, if the property mentioned on this question was not flagged as an event, the code below will case the two first assignments to be LOST, because someone simply assigned to the delegate (which is also valid!).
myObject.MyEvent += Method1;
myObject.MyEvent += Method2;
myObject.MyEvent = Method3;
When assigning Method3, I completely lost the two initial subscriptions. Event usage will avoid this problem and at same time remove the ReSharper warning.