문제

나는 기본 클래스 DockedToolwindow : Form 및 DockedToolwindow에서 파생되는 많은 클래스가 있습니다. 나는 컨테이너 클래스를 보유하고 이벤트를 dockedtoolwindow 객체에 할당하지만 어린이 수업에서 이벤트를 호출하고 싶습니다.

나는 실제로 이것을 구현하는 방법에 대한 질문이 있습니다. MSDN 사이트 나에게하라고 말하고있다. 아래 섹션은 나에게 문제를 준다 :

    // The event. Note that by using the generic EventHandler<T> event type
    // we do not need to declare a separate delegate type.
    public event EventHandler<ShapeEventArgs> ShapeChanged;

    public abstract void Draw();

    //The event-invoking method that derived classes can override.
    protected virtual void OnShapeChanged(ShapeEventArgs e)
    {
        // Make a temporary copy of the event to avoid possibility of
        // a race condition if the last subscriber unsubscribes
        // immediately after the null check and before the event is raised.
        EventHandler<ShapeEventArgs> handler = ShapeChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

이 예제는 컴파일되고 작동하지만 "Shapechanged"를 "Move"(양식에서 파생에서 얻은 이벤트)로 바꾸면 += 또는 -=없이 오른쪽으로 이동할 수 없다는 오류가 발생합니다. 또한 Shapeeventargs 일반 태그를 제거했습니다.

이것이 작동하지 않는 이유에 대한 자극이 있습니까? 수업 내에서 선언 된 이벤트와 상속 된 이벤트의 차이점은 무엇입니까?

도움이 되었습니까?

해결책

기본 클래스 이벤트를 직접 발사 할 수 없습니다. 이것이 바로 당신이 당신의 OnShapeChanged 방법 protected 대신에 private.

사용 base.onmove () 대신에.

다른 팁

C# 언어 사양, 섹션 10.7 (강조 추가) :

이벤트 선언이 포함 된 클래스 또는 구조물의 프로그램 텍스트 내에서 특정 이벤트는 필드처럼 사용할 수 있습니다.. 이런 식으로 사용하려면 이벤트는 추상적이거나 외부가되어서는 안되며, 이벤트 액세서 선반을 명시 적으로 포함해서는 안됩니다. 이러한 이벤트는 필드를 허용하는 모든 상황에서 사용할 수 있습니다. 이 필드에는 이벤트에 추가 된 이벤트 핸들러 목록을 나타내는 대의원 (§15)이 포함되어 있습니다. 이벤트 핸들러가 추가되지 않은 경우 필드에는 NULL이 포함되어 있습니다.

따라서 이동 이벤트를 필드처럼 취급 할 수없는 이유는 다른 유형 (이 경우 슈퍼 클래스)으로 정의되기 때문입니다. 나는 디자이너들이 의도하지 않은 원숭이를 이벤트로 막기 위해이 선택을했다는 @WOMP의 추측에 동의합니다. 관련없는 유형 (이벤트 선언 유형에서 파생되지 않은 유형)이이를 수행하도록 허용하는 것은 분명히 나쁘지만, 파생 된 유형의 경우에도 바람직하지 않을 수 있습니다. 그들은 아마도 이벤트 선언을 허용하기 위해 구문을 포함시켜야했을 것입니다. private 또는 protected 필드 스타일의 사용법과 관련하여, 내 추측은 그들이 그것을 완전히 허용하지 않기로 결정했다는 것입니다.

차이점은 범위입니다. 수업 내에서는 이벤트 대의원이 어떻게 처리되는지 제어 할 수 있지만, 수업은 기본 클래스가 수행하는 일을 제어 할 수 없습니다. 이벤트와 처리기와 함께 미친 비하인드 스토리 작업을 수행 할 수 있습니다. 단순히 움직임 이벤트를 "재 할당"하면 이벤트의 멀티 캐스트 대의원 목록을 닦을 것입니다.

나는 그들이 매우 안전하지 않은 연습이기 때문에 그들이 이것에 대해 컴파일러 제한을 한 것 같아요. 그리고 본질적으로 자손 계급은 부모의 이벤트 모델을 파괴 할 수있는 능력을 제공 할 것입니다.

이벤트 자체가 정의 된 클래스에 게시 한 코드 만 필요합니다. 모든 파생 된 클래스는 단순히 복사 등없이 OnShapEchanged () 또는 onmove ()를 직접 호출해야하므로 클래스에서 해당 코드를 전혀 쓰지 않아야합니다 (이동 이벤트가 기본에 정의되기 때문에).

파생 클래스에서 어떤 종류의 처리를 수행 해야하는 경우 (컬렉션 클래스와 함께 바이올린이 필요합니까?) 가상 ONXXX 호출을 무시하고 base.onxxx ()를 호출하기 전에 물건을 수행하십시오. MSDN 기사에서 Circle 클래스는 DockedToolwindow 클래스에 해당합니다. 파생 클래스에서도 동일한 패턴을 사용할 수 있어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top