2011-08-20 3 views
6

나는 다음과 같은 코드를 작성하는 경우,커스텀 접근자를 가진 이벤트를 기본 이벤트와 같이 직접 실행할 수없는 이유는 무엇입니까?

class MainClass 
{ 
    static EventHandler _myEvent= delegate{}; 
    static event EventHandler MyEvent 
    { 
     add{_myEvent += value;} 
     remove{_myEvent -= value;} 
    } 

    public static void Main (string[] args) 
    { 
     MyEvent(null,EventArgs.Empty); 
    } 
} 

컴파일러가 불평 할 것이다 : 오류 CS0079을 : 이벤트 MainClass.MyEvent' can only appear on the left hand side of + = '또는'- = '연산자를.

왜 이런 이상한 것이 존재합니까? 직접 이벤트를 실행할 수없는 경우 왜 처음부터 그런 것을 사용해야합니까? 그 버그 (나는 모노를 사용하고있다) 또는 고의적 인 섬세한 디자인인가? 아무도 나에게이 배후의 논리를 가르쳐 주시겠습니까? 미리 감사드립니다.

답변

2

선언 클래스에서 이벤트에만 액세스 할 수 있습니다. 비하면, .NET은 대리자를 보유 할 개인 인스턴스 변수를 만듭니다.

컴파일러는 실제로 공용 이벤트 및 개인 필드를 만듭니다. 동일한 클래스 또는 중첩 클래스에서 직접 필드에 액세스 할 수 있습니다. 외부 수업에서는 구독/탈퇴 만 허용됩니다.

Jon Skeet의 멋진 정보는 이유 및 작동 원리에 대해 here에 나와 있습니다.

+0

여기에는 문제가 없습니다. 선언 클래스 내에서 _is_ 이벤트에 액세스하려는 시도 ... –

+0

@ 닉 : 아니요, 무슨 일이 벌어지고 있는지 절대적으로 말합니다 : 필드와 비슷한 이벤트의 경우 호출을 호출하는 것으로 실제로 호출됩니다 . 그런 다음 지식을 가져와 맞춤 이벤트에 적용합니다. 즉, 뒷 필드를 통해 * 호출합니다. –

+0

@ 존 : CS0079 오류를 이해하기 위해 필드와 유사한 이벤트가 어떻게 구현되었는지 역으로 해결할 수 있다는 것에 동의합니다. 대답이 집중되어 있었다면, 그것은 +1이었을 것입니다. 그러나이 대답은 현장의 사적 접근성에 초점을 맞추고 있으며, 그 점은 그 지점에 있습니다. –

2

이벤트를 발생 시키려면 수동으로 선언 된 백업 대리인을 호출해야합니다. MyEvent(null, EventArgs.Empty)_myEvent(null, EventArgs.Empty)으로 바꿉니다. 생각해 보면 사용자 지정 추가/제거는 대리자를 어디서나 저장할 수 있기 때문에 사용자가 직접 작성한 방식대로 검색하고 호출 할 수 없습니다.

+0

:하지만, 만약 내가 원한다면 클래스를 파생시키고 하위 클래스에 기본 대리자 필드를 표시하고 싶지 않습니다. 그건 엉망이 될거야, 그렇지? 방금 하위 클래스가 기본 클래스의 이벤트를 실행하지 못하는 것을 관찰했습니다.이 디자인은 다소 약하지 않습니까? 이벤트는 외부인이 그것을 망칠 수 없도록하기 위해 사용됩니다. 그러나 내부자가 왜 제한적입니까? – Need4Steed

+0

권장되는 패턴은 이벤트를 발생시키는 보호 된 가상 메서드를 제공하는 것입니다. http://msdn.microsoft.com/en-us/library/ms229011.aspx. –

+1

링크 해 주셔서 감사합니다. 그러나, 나는 여전히 불투명 디자인이 꽤 절름발이라고 생각한다. 이벤트는 가상 일 수도 있고 서브 클래스에 의해 무시 될 수도 있습니다.하지만 이벤트를 발생 시키려면 몇 가지 도우미 가상 메소드를 사용해야합니다. 어떻게 절름발이가 아닌지? – Need4Steed

관련 문제