[C#] ReSharper / C #에서 “대리자 빼기 결과를 예측할 수 없습니다”?

사용하는 경우 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
    }
}



답변

두려워하지 마세요! ReSharper 경고의 첫 번째 부분은 대리인 목록 제거에만 적용됩니다. 코드에서 항상 단일 대리자를 제거합니다. 두 번째 부분에서는 중복 델리게이트가 제거 된 후 델리게이트 순서에 대해 설명합니다. 이벤트는 구독자의 실행 순서를 보장하지 않으므로 실제로 사용자에게 영향을 미치지 않습니다.

위의 메커니즘은 예측할 수없는 결과를 초래할 수 있으므로 ReSharper는 대리자 빼기 연산자를 만날 때마다 경고를 발행합니다.

ReSharper는 멀티 캐스트 대리자 감산에 문제가있을 수 있기 때문에이 경고를 발행하지만 해당 언어 기능을 완전히 비난하지는 않습니다. 운 좋게도 이러한 문제는 특수한 경우에 있으며 단순한 이벤트를 계측하는 경우에는 이러한 문제가 발생할 가능성이 거의 없습니다. 자신의 add/ remove핸들러 를 구현하는 더 좋은 방법은 없습니다 .주의해야합니다.

일반적으로 유용한 경고에 민감하지 않도록 해당 메시지에 대한 ReSharper의 경고 수준을 “힌트”로 다운 그레이드하는 것이 좋습니다.


답변

합계 또는 빼기 위해 대리자를 직접 사용해서는 안됩니다. 대신 당신의 분야

MyHandler _myEvent;

대신 이벤트로 선언되어야합니다. 이렇게하면 솔루션을 위험에 빠뜨리지 않고 문제가 해결되고 이벤트 사용의 이점이 있습니다.

event MyHandler _myEvent;

델리게이트 합계 또는 빼기 사용은 단순히 델리게이트를 할당 할 때 이벤트를 잃을 수 있기 때문에 위험합니다 (선언에 따라 개발자는 이것이 이벤트로 선언 될 때 멀티 캐스트 델리게이트임을 직접 추론하지 않습니다). 예를 들어,이 질문에 언급 된 속성이 이벤트로 플래그가 지정되지 않은 경우 아래 코드는 누군가가 단순히 대리인에게 할당 되었기 때문에 (유효합니다!) 두 개의 첫 번째 할당이 LOST로 간주됩니다.

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

Method3을 할당 할 때 두 개의 초기 구독을 완전히 잃었습니다. 이벤트 사용은이 문제를 방지하고 동시에 ReSharper 경고를 제거합니다.


답변

-=를 사용하는 대신 = null로 설정하십시오.


답변