[C#] C # : 상속 된 이벤트 발생

다음과 같은 이벤트가 포함 된 기본 클래스가 있습니다.

public event EventHandler Loading;
public event EventHandler Finished;

이 기본 클래스에서 상속받은 클래스에서 이벤트를 발생시킵니다.

this.Loading(this, new EventHandler()); // All we care about is which object is loading.

다음과 같은 오류가 발생합니다.

‘BaseClass.Loading’이벤트는 + = 또는-= (BaseClass ‘)의 왼쪽에만 표시 될 수 있습니다.

상속받은 다른 회원과 동일한 이벤트에 액세스 할 수 없다고 가정합니다.



답변

당신이해야 할 일은 이것입니다 :

이벤트를 선언 한 기본 클래스에서 이벤트를 발생시키는 데 사용할 수있는 보호 된 메소드를 작성하십시오.

public class MyClass
{
   public event EventHandler Loading;
   public event EventHandler Finished;

   protected virtual void OnLoading(EventArgs e)
   {
       EventHandler handler = Loading;
       if( handler != null )
       {
           handler(this, e);
       }
   }

   protected virtual void OnFinished(EventArgs e)
   {
       EventHandler handler = Finished;
       if( handler != null )
       {
           handler(this, e);
       }
   }
}

이벤트 핸들러를 호출해야하는지 여부를 확인하려면 해당 메소드를 변경해야합니다.

그런 다음이 기본 클래스에서 상속 된 클래스에서 OnFinished 또는 OnLoading 메소드를 호출하여 이벤트를 발생시킬 수 있습니다.

public AnotherClass : MyClass
{
    public void DoSomeStuff()
    {
        ...
        OnLoading(EventArgs.Empty);
        ...
        OnFinished(EventArgs.Empty);
    }
}


답변

.NET은 실제로 델리게이트를 보유하는 씬 뒤에 프라이빗 인스턴스 변수를 생성하므로 선언 클래스의 이벤트에만 액세스 할 수 있습니다. 이거 ..

public event EventHandler MyPropertyChanged;

실제로이 작업을 수행하고 있습니다.

private EventHandler myPropertyChangedDelegate;

public event EventHandler MyPropertyChanged
{
    add { myPropertyChangedDelegate += value; }
    remove { myPropertyChangedDelegate -= value; }
}

그리고 이걸 …

MyPropertyChanged(this, EventArgs.Empty);

실제로 이것은 …

myPropertyChangedDelegate(this, EventArgs.Empty);

따라서 선언 클래스 내에서만 private 대리자 인스턴스 변수에만 액세스 할 수 있습니다.

컨벤션은 선언 클래스에서 이와 같은 것을 제공하는 것입니다.

protected virtual void OnMyPropertyChanged(EventArgs e)
{
    EventHandler invoker = MyPropertyChanged;

    if(invoker != null) invoker(this, e);
}

그런 다음 OnMyPropertyChanged(EventArgs.Empty)해당 클래스의 어느 곳에서나 상속 계층 아래에서 호출하여 이벤트를 호출 할 수 있습니다.


답변

상속받은 다른 회원과 동일한 이벤트에 액세스 할 수 없다고 가정합니다.

정확하게. 상속 된 클래스에서 발생시킬 수 있도록 보호 된 기능을 제공 OnXyz하거나 RaiseXyz기본 클래스의 각 이벤트에 대해 관례 입니다. 예를 들면 다음과 같습니다.

public event EventHandler Loading;

protected virtual void OnLoading() {
    EventHandler handler = Loading;
    if (handler != null)
        handler(this, EventArgs.Empty);
}

상속 된 클래스에서 호출됩니다.

OnLoading();


답변

이 방법으로 시도해 볼 수 있습니다.

public delegate void MyEventHaldler(object sender, EventArgs e);

public class B
{
    public virtual event MyEventHaldler MyEvent;
    protected override void OnChanged(EventArgs e)
    {
        if (MyEvent != null)
            MyEvent(this, e);
    }
}

public class D : B
{
    public override event MyEventHaldler MyEvent;
    protected override void OnChanged(EventArgs e)
    {
        if (MyEvent != null)
            MyEvent(this, e);
    }
}


답변

오래된 실을 되 살릴 수는 없지만 누군가 가보고있는 경우, 내가 한 일은

protected EventHandler myPropertyChangedDelegate;

public event EventHandler MyPropertyChanged
{
    add { myPropertyChangedDelegate += value; }
    remove { myPropertyChangedDelegate -= value; }
}

이렇게하면 파생 클래스에서 이벤트를 상속 할 수 있으므로 + = 구문을 유지하면서 메서드를 래핑하지 않고도 호출 할 수 있습니다. 그래도 랩핑 방법으로 그렇게 할 수 있다고 생각합니다.

public event EventHandler MyPropertyChanged
{
   add { AddDelegate(value); }
   remove { RemoveDelegate(value); }
}


답변