문제

다음 C# 클래스를 선택하십시오.

c1 {
 event EventHandler someEvent;
}

구독이 많은 경우 c1'에스 someEvent 이벤트와 나는 그들 모두를 정리하고 싶습니다. 이것을 달성하는 가장 좋은 방법은 무엇입니까? 또한이 이벤트에 대한 구독은 Lambdas/익명 대의원 일 수 있습니다.

현재 내 솔루션은 a를 추가하는 것입니다 ResetSubscriptions() 방법 c1 그 세트 someEvent null에. 이것이 보이지 않는 결과가 있는지 모르겠습니다.

도움이 되었습니까?

해결책

클래스 내에서 (숨겨진) 변수를 null로 설정할 수 있습니다. Null 참조는 빈 호출 목록을 효과적으로 나타내는 표준 방법입니다.

수업 밖에서, 당신은 이것을 할 수 없습니다 - 이벤트는 기본적으로 "구독"과 "수신 거부"를 드러냅니다.

필드와 같은 이벤트가 실제로 무엇을하고 있는지 알고 있어야합니다. 그들은 변수를 생성합니다. 그리고 동시에 이벤트. 수업 내에서 변수를 참조하게됩니다. 외부에서 이벤트를 참조하십시오.

내 참조 이벤트 및 대표에 관한 기사 자세한 내용은.

다른 팁

'sodyevent'를 null로 설정하는 메소드를 C1에 추가하십시오 ...

class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = null;}
}
class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = delegate{};}
}

NULL보다 Delegate {}를 사용하는 것이 좋습니다.

수업 내에서 이벤트를 Null로 설정합니다. 클래스를 처분 할 때는 항상 이벤트를 NULL로 설정해야하며 GC는 이벤트에 문제가 있으며 매달려있는 이벤트가있는 경우 폐기 클래스를 정리하지 않을 수 있습니다.

모든 가입자를 지우는 모범 사례는이 기능을 외부에 노출하려는 경우 다른 공개 메소드를 추가하여 NULL로 설정하는 것입니다. 이것은 보이지 않는 결과가 없습니다. 전제 조건은 키워드 '이벤트'를 선언하는 것을 기억하는 것입니다.

125 페이지의 간단히 말해서 책 -C# 4.0을 참조하십시오.

여기에 어떤 사람은 사용을 제안했습니다 Delegate.RemoveAll 방법. 사용하면 샘플 코드가 아래 양식을 따를 수 있습니다. 그러나 정말 바보입니다. 왜 그냥 SomeEvent=null 내부 ClearSubscribers() 기능?

   public void ClearSubscribers ()
    {
          SomeEvent = (EventHandler) Delegate.RemoveAll(SomeEvent, SomeEvent);// Then you will find SomeEvent is set to null.
    }

Delegate.Remove 또는 Delegate.Removeall 메소드를 사용하여이를 달성 할 수 있습니다.

개념적 확장 지루한 의견.

차라리 "이벤트"또는 "델리게이트"대신 "이벤트 핸들러"라는 단어를 사용합니다. 다른 물건에 "이벤트"라는 단어를 사용했습니다. 일부 프로그래밍 언어 (vb.net, 객체 Pascal, Objective-C), "이벤트"는 "메시지"또는 "신호"라고하며 "메시지"키워드 및 특정 설탕 구문이 있습니다.

const
  WM_Paint = 998;  // <-- "question" can be done by several talkers
  WM_Clear = 546;

type
  MyWindowClass = class(Window)
    procedure NotEventHandlerMethod_1;
    procedure NotEventHandlerMethod_17;

    procedure DoPaintEventHandler; message WM_Paint; // <-- "answer" by this listener
    procedure DoClearEventHandler; message WM_Clear;
  end;

그리고 그 "메시지"에 응답하기 위해 "이벤트 핸들러"는 단일 대의원이든 여러 대의원이든 응답합니다.

요약 : "이벤트"는 "질문", "이벤트 핸들러"는 답입니다.

이것은 내 해결책입니다.

public class Foo : IDisposable
{
    private event EventHandler _statusChanged;
    public event EventHandler StatusChanged
    {
        add
        {
            _statusChanged += value;
        }
        remove
        {
            _statusChanged -= value;
        }
    }

    public void Dispose()
    {
        _statusChanged = null;
    }
}

전화해야합니다 Dispose() 또는 사용 using(new Foo()){/*...*/} 호출 목록의 모든 멤버를 구독하지 않는 패턴.

모든 이벤트를 제거하고 이벤트가 "액션"유형이라고 가정합니다.

Delegate[] dary = TermCheckScore.GetInvocationList();

if ( dary != null )
{
    foreach ( Delegate del in dary )
    {
        TermCheckScore -= ( Action ) del;
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top