2011-01-20 8 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(); 
     } 
    } 
} 

これは動作しません。私は基本クラスからイベントにしかアクセスできません。

(イベントの呼び出しをチェックし、そのメソッドを子クラスから呼び出す保護されたメソッドを基本クラスに追加するのは)難しいことではありませんが、この制限の背後にあるアイデアは本当に何ですか?

乾杯、

SEBI

+0

が重複する可能性をC#の基本クラスの派生クラスと同じ方法ですか?]](http://stackoverflow.com/questions/253757/why-events-cant-be-used-in-theame-way-in-derived-クラスとしてのベースクラス) –

答えて

13

あなたは、それが定義された内のクラスの外からのイベントを呼び出すことはできません。しかし、あなたはそうする必要はありません。そのイベントを起こすための保護された方法を宣言するという慣用的な方法に従ってください。

class Whatever 
{ 
    public event EventHandler Foo; 

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

今、 "Whatever"クラスの子孫は、OnFoo()を呼び出して適切なEventArgsオブジェクトを渡すことでイベントを発生させることができます。

EDIT:

あなたが宣言すると:これは動作である理由に関しては、ジョンスキートは(そう閉じるに投票、またこの質問が重複していることを意味する)だけでなく、別のスレッドでそれを説明しましたパブリックフィールドのようなイベントでは、コンパイラはパブリックイベントとプライベートフィールドを作成します。同じクラス(またはネストされたクラス)内では、フィールドに直接アクセスできます。すべてのハンドラを呼び出す。他のクラスからは、イベントのみが表示され、サブスクリプションとサブスクライブ解除のみが許可されます。

+0

私はこれを知らなかった。ニースの情報。 –

+0

これは私が今行ったことです! –

+0

問題ありません、このスレッドで詳細を確認してください:http://stackoverflow.com/questions/253757/why-events-cant-be-used-in-the-same-way-in-derived-classes-as- in-the-base-class#253803 –

3

あなたはあなたの例では、イベントを宣言するために使用される構文は、実際にこのような何かのためのシンタックスシュガーです:

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

(実際のコードはもちろん、もう少し複雑です)

ここで重要な部分は、_actionRequiredフィールドがプライベートであることです。イベント自体は公開されているだけですが、プロパティのような追加/削除メソッドのペアです。あなたがイベントで唯一できることは、それを購読または購読中止することです。実際のデリゲートを保持するフィールドはプライベートなので、それを宣言するクラスからのみアクセスできます。それを宣言するクラスでActionRequiredを使用すると、コンテキストに応じてデリゲートフィールドまたはイベント自体を参照します。

他のクラスからは、フィールドではなくイベントのみがアクセス可能です。そのため、派生クラスでも、別のクラスからデリゲートを呼び出すことはできません。

+0

このことがどうなるかを理解するのに役立つ@Thomasに感謝します –

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(); 
    } 
} 
関連する問題