2011-11-15 2 views
6

C#을 이벤트와 클래스 메소드 :나는 이런 식으로 뭔가 할 경우 내가 궁금하네요

class A 
{ 
    public MethodA() 
    { 
    } 
    public MethodB() 
    { 
     ExternalObject.Click += this.MethodA; 
    } 
    public MethodC() 
    { 
     ExternalObject.Click -= this.MethodA; 
    } 
} 

A a = new A(); 
a.MethodB(); 
a.MethodC(); 

이 작업을 예정을? "작품"으로 말하자면 - MethodA는 ExternalObject.Click 이벤트에서 구독 취소됩니까?

및 기타 관련 질문 :

인스턴스 메서드 대신 위임 인스턴스로 사용하는 경우 내부적으로 어떻게됩니까

? (위와 같음)

이것은 대리인의 암시 적 생성을 유발합니까?

-= 연산자가 델리게이트를 비교하는 방법은 무엇입니까? - 참조 또는 좀 더 정교한 일이 발생합니까?

답변

8

예, 원하는대로 작동합니다.

비교는 참조가 아니라 값으로, 동일한 개체의 동일한 메서드를 가리키는 한 다른 대리인의 수신을 취소 할 수 있음을 의미합니다. 즉

, 이것은 잘 작동합니다 :

var delegate1 = new ExternalObjectClickEventHandler(MethodA); 
var delegate2 = new ExternalObjectClickEventHandler(MethodA); 
ExternalObject.Click += delegate1; 
ExternalObject.Click -= delegate2; 
, 당신이 비록 다른 할 수 있습니다

익명 방법 : 방법이 같은 코드를 포함하는 동안

public MethodB() 
{ 
    ExternalObject.Click +=() => { return 10; }; 
} 

public MethodC() 
{ 
    ExternalObject.Click -=() => { return 10; }; 
} 

는, 그들은 간주됩니다 다른, 따라서이 작동하지 않습니다, 즉, MethodCMethodB에 추가 한 대리인을 구독 취소하지 않습니다.

private ExternalObjectClickEventHandler _ClickEventHandler; 
public MethodB() 
{ 
    _ClickEventHandler =() => { return 10; }; 
    ExternalObject.Click += _ClickEventHandler; 
} 

public MethodC() 
{ 
    ExternalObject.Click -= _ClickEventHandler; 
} 

을하지만 보여 코드는 작동합니다

이 문제를 해결하려면 다음과 같이 호출 사이 대리자를 저장해야합니다.

이 두 번째 코드는 처음부터 무엇을 생성한다
ExternalObject.Click += MethodA; 
ExternalObject.Click += new ExternalObjectClickEventHandler(MethodA); 

(가정 : 그것은 생성 된 코드에 올 때 무대 뒤에서 무슨 일 귀하의 질문에 관해서는

는 다음 두 줄의 코드가 동일하다는 것입니다 이벤트의 유형은 그림과 같습니다.)

첫 번째 구문은 두 번째 구문을 작성한 것처럼 컴파일러에서 번역 된 "구문 설탕"으로 추가되었습니다 (일부 지점). 컴파일 된 것이 올바른 유형의 100 %를 찾아 낼 수있는 경우에만 발생합니다. 필자는 컴파일러가 당신이 의미하는 것을 이해할 수 없기 때문에 정규화 된 구문을 사용해야하는 경우 (지금 기억할 수없는 경우)를 보았습니다. 특히 메서드 오버로드와 제네릭은 이러한 점에서이를 혼동시킬 수 있습니다.

+0

철저한 답변에 감사드립니다. – kubal5003

3

예, MethodA은 수신 거부됩니다.

두 번째 질문에 대해서는 100 % 확신 할 수는 없지만 백그라운드에서 대리자로 변환되는 것은 = this.MethodA입니다.

+0

+1. 'this.MethodA'는 암시 적으로 델리게이트로 변환 될 것입니다. – kol

관련 문제