2016-07-26 2 views
0

I 간단한 추상 클래스 가지고호출베이스 이벤트 핸들러 6

abstract class Lesson 
{ 
    public event EventHandler<SpeakEventArgs> Speak; 
    public string OpeningMessage { get; set; } 
    public string ClosingMessage { get; set; } 
    public bool completed { get; private set; } = false; 
    abstract public void Do(); 
} 

및 단순한 서브 클래스 :

class BubbleSort : Lesson 
{ 
    public override void Do() 
    { 
     base.Speak?.Invoke(this, new SpeakEventArgs { Message = OpeningMessage }); 
    } 
} 

서브 클래스는 C# 6 널 조건 연산자를 사용을 ?.. 이 코드는 오류를

이벤트를 제공 'Lesson.Speak'단의 좌측에 나타날 수 + = 또는 - = 분명히

(유형 '장'에서 사용하는 경우를 제외하고) 하위 클래스로 '레슨'유형 안에 있습니다. 하위 클래스 내에서 기본 클래스 이벤트 호출을 어떻게 수행합니까?

답변

0

당신은 대신 난을 만들어 제안

에 선언 된 것 이외의 모든 클래스에서 이벤트를 호출 할 수 없습니다 다음 필요한 검사를 수행하여 기본 클래스의 방법을 인상하면

protected void raiseSpeak(SpeakEventArgs args) 
{ 
    this.Speak?.Invoke(sender, args); 
} 

또는 귀하의 경우

단지 DO에서 추상을 제거하기위한 이벤트를 발생 그런 다음, 예를 들어, 선택적으로 오버라이드 (override) 할 수있는

abstract class Lesson 
{ 
    public event EventHandler<SpeakEventArgs> Speak; 
    public string OpeningMessage { get; set; } 
    public string ClosingMessage { get; set; } 
    public bool completed { get; private set; } = false; 
    abstract public void Do(); 

    protected virtual void RaiseSpeak(object sender, SpeakEventArgs args) 
    { 
     this.Speak?.Invoke(sender, args); 
    } 
} 

: 및 예를 들어, 당신이 다음 추가 기능

abstract class Lesson 
{ 
    public event EventHandler<SpeakEventArgs> Speak; 

    public virtual void Do() 
    { 
     this.Speak?.Invoke(sender, args); 
    } 
} 

class BubbleSort : Lesson 
{ 
    public override void Do() 
    { 
     base.Do(); 
     //do something BubbleSort related 
    } 
} 
1

은 하위 클래스 에서조차도 해당 클래스를 정의하는 클래스 외부에서 직접 이벤트를 호출 할 수 없습니다.

해결 방법을 발사하는 protected 방법을 사용하십시오

internal abstract class Lesson 
{ 
    public event EventHandler<SpeakEventArgs> Speak; 

    public string OpeningMessage { get; set; } 
    public string ClosingMessage { get; set; } 
    public bool completed { get; private set; } = false; 

    abstract public void Do(); 

    protected void DoSpeak(SpeakEventArgs e) 
    { 
     if (this.Speak != null) 
     { 
      this.Speak(this, e); 
     } 
    } 
} 

internal class BubbleSort : Lesson 
{ 
    public override void Do() 
    { 
     base.DoSpeak(new SpeakEventArgs { Message = OpeningMessage }); 
    } 
} 
+0

'this.Speak (this, e);'는 스레드로부터 안전하지 않으므로 null 체크와 호출 사이에 이벤트가 수신 거부 될 수 있습니다. 대신 핸들러를 객체에 복사 한 다음 확인해야합니다 거기에서 null과 call을 위해 – MikeT

+1

@MIkeT는 당신에게 절대 아무것도주지 않습니다. 당신은 단순히 그것을 없애지 않고 경쟁 조건을 바꾸고 있습니다. 이제는 안되면 행사가 시작됩니다. – InBetween

+1

@MikeT 예, 스레드로부터 안전하지는 않지만 가장하지는 않습니다. 당신이 제안한 것도 그 중 하나가 아닙니다. 그것은 실제로 일반적인 실수입니다. 그렇게해서는 안됩니다. http://blog.stephencleary.com/2009/06/threadsafe-events.html – ken2k

0

You will have to provide a raise method in your abstract class를 오버라이드 (override) 할 수 있습니다 레슨 클래스,의 DO 방식의 이벤트를 발생

class BubbleSort : Lesson 
{ 
    protected override void RaiseSpeak(object sender, SpeakEventArgs args) 
    { 
     // your logic here 

     base.RaiseSpeak(sender, args); 
    } 

    public override void Do() 
    { 
     this.RaiseSpeak(this, new SpeakEventArgs() { Message = OpeningMessage }); 
    } 
}