127

使用myDelegate -= eventHandlerReSharper(版本 6)时出现问题:

委托减法具有不可预测的结果

JetBrains 在这里解释了这背后的原因。这个解释是有道理的,读完之后,我怀疑我-对代表的所有使用。

那么如何

  • 我可以在不让 ReSharper 脾气暴躁的情况下编写非自动事件吗?
  • 或者,是否有更好和/或“正确”的方法来实现这一点?
  • 或者,我可以忽略 ReSharper 吗?

这是简化的代码:

public delegate void MyHandler (object sender);

MyHandler _myEvent;

public event MyHandler MyEvent
{
    add
    {
        _myEvent += value;
        DoSomethingElse();
    }
    remove
    {
        _myEvent -= value; // <-- ReSharper warning here
    }
}
4

3 回答 3

139

不要害怕!ReSharper 警告的第一部分仅适用于删除代表列表。在您的代码中,您总是删除一个委托。第二部分讨论了删除重复代表后代表的顺序。事件并不能保证其订阅者的执行顺序,因此它也不会真正影响您。

由于上述机制可能导致不可预知的结果,因此 ReSharper 在遇到委托减法运算符时会发出警告。

ReSharper 发出此警告是因为多播委托减法可能有问题,它并没有完全谴责该语言功能。幸运的是,这些陷阱存在于边缘案例中,如果您只是检测简单事件,则不太可能遇到它们。没有更好的方法来实现您自己的add/remove处理程序,您只需要注意。

我建议将该消息的 ReSharper 警告级别降级为“提示”,这样您就不会对他们的警告不敏感,这通常很有用。

于 2012-06-24T18:32:14.000 回答
30

您不应该直接使用委托来求和或减法。取而代之的是你的领域

MyHandler _myEvent;

相反,也应该将其声明为事件。这将解决问题而不会危及您的解决方案,并且仍然具有事件使用的好处。

event MyHandler _myEvent;

使用委托总和或减法是危险的,因为您在简单地分配委托时可能会丢失事件(根据声明,开发人员不会直接推断这是一个多播委托,因为它被声明为一个事件)。举个例子,如果这个问题中提到的属性没有被标记为事件,下面的代码会将前两个分配丢失,因为有人简单地分配给了委托(这也是有效的!)。

myObject.MyEvent += Method1; 
myObject.MyEvent += Method2;
myObject.MyEvent = Method3;

在分配 Method3 时,我完全失去了两个初始订阅。事件使用将避免此问题,同时删除 ReSharper 警告。

于 2015-10-28T16:12:14.250 回答
-17

将其设置为 = null 而不是使用 -=

于 2015-02-23T16:55:50.840 回答