2011-01-20 50 views
5

以前從來沒有遇到過。這裏的示例:c#:訪問父類的事件不可能嗎?

using System; 

namespace Testing 
{ 
    public class Test 
    { 
     public event Action ActionRequired; 
    } 

    public class ChildTest : Test 
    { 
     public void DoSomething() 
     { 
      if (this.ActionRequired != null) 
       this.ActionRequired(); 
     } 
    } 
} 

這將無法正常工作,錯誤是我只能從基類訪問事件。

這不是一帆風順(給基類添加一個受保護的方法,它既檢查事件的調用,也從子類調用該方法),但我真的很想知道這個限制背後的想法是什麼?

乾杯,

塞比

+0

可能重複在派生類中的相同方式與在C#中的基類?](http://stackoverflow.com/questions/253757/why-events-cant-be-used-in-the-same-way-in-derived-班級作爲基礎班) – 2011-01-20 00:17:29

回答

13

您不能調用從內定義它們的類之外的事件。但是,你不需要;只要按照習慣性的模式也宣佈一個受保護的方法來解僱所說的事件。

class Whatever 
{ 
    public event EventHandler Foo; 

    protected virtual void OnFoo(EventArgs e) 
    { 
     EventHandler del = Foo; 
     if(del != null) 
     { 
      del(this, e); 
     } 
    } 
} 

類「無論」現在的後代可以通過調用OnFoo()並傳遞適當的EventArgs對象來觸發事件。

編輯:在關於爲什麼是這樣的行爲,喬恩斯基特解釋它做好在另一個線程(這也意味着,這個問題是一個重複的,所以投票關閉):

在聲明公共領域事件,編譯器創建一個公共事件和一個私人領域。在同一類(或嵌套類)中,你可以直接在現場得到,例如調用所有的處理程序。從其他課程中,您只能看到僅允許訂閱和取消訂閱的活動。

+0

我從來不知道這一點。很好的信息。 – 2011-01-20 00:15:26

+0

謝謝,這就是我現在所做的! – 2011-01-20 00:16:59

3

你用來聲明在你的榜樣事件的語法是這樣的事情其實語法糖:

private Action _actionRequired; 
public event Action ActionRequired 
{ 
    add { _actionRequired += value; } 
    remove { _actionRequired -= value } 
} 

(實際的代碼當然是更復雜一點)

的這裏的重要部分是_actionRequired字段是私人的。只有事件本身是公開的,但它只是一對添加/刪除方法(類似於屬性)。因此,您可以對該事件做的唯一事情是訂閱或取消訂閱。包含實際委託的字段是私有的,因此只能從聲明它的類訪問。當在聲明它的類中使用ActionRequired時,它根據上下文將其引用到委託字段或事件本身。

但是,從任何其他課程,只有該事件是可訪問的,而不是字段。這就是爲什麼你不能從另一個類,甚至派生類中調用委託。

1

按照由@ThomasLevesque 添加https://stackoverflow.com/a/4742280/3926461

你可以宣佈你的行動,而無需使用此語法糖像下面以前的答案:

public class Test 
{ 
    protected Action _actionRequired; 
    public event Action ActionRequired { 
     add { 
      _actionRequired += value; 
     } 
     remove { 
      _actionRequired += value; 
     } 
    } 
} 

public class ChildTest : Test 
{ 
    public void DoSomething() 
    { 
     if (this._actionRequired != null) 
      this._actionRequired(); 
    } 
} 
的[事件爲什麼不能使用