ReSharper/C# 中的“委托减法具有不可预测的结果”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11180068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:53:53  来源:igfitidea点击:

"Delegate subtraction has unpredictable result" in ReSharper/C#?

c#eventsdelegatesresharpercompiler-warnings

提问by

When using myDelegate -= eventHandlerReSharper (version 6) issues:

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

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.

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

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

采纳答案by Allon Guralnek

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.

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

Since the above mechanics can lead to unpredictable results, ReSharper issues a warning whenever it encounters a delegate subtraction operator.

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

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/removehandlers, you just gotta take notice.

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

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.

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

回答by Jonathan Beresford

set it to = null instead of using -=

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

回答by blimac

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.

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