2011-08-20 15 views
6

私は以下のようなコードを記述する場合、カスタムアクセサのイベントは、デフォルトのイベントと同じように直接起動できないのはなぜですか?

class MainClass 
{ 
    static EventHandler _myEvent= delegate{}; 
    static event EventHandler MyEvent 
    { 
     add{_myEvent += value;} 
     remove{_myEvent -= value;} 
    } 

    public static void Main (string[] args) 
    { 
     MyEvent(null,EventArgs.Empty); 
    } 
} 

コンパイラが文句を言うだろう:エラーCS0079を:イベントMainClass.MyEvent' can only appear on the left hand side of + = 'または ` - =' 演算子を。

なぜこのような変わったものが存在しますか?私がイベントを直接発射できない場合、なぜ私はそのようなことを最初に使用しますか?それはバグですか(私はモノを使用していますか)、または繊細なデザインを検討していますか?誰でもこの背後にある根拠を教えてもらえますか?前もって感謝します。

答えて

2

イベントは、宣言クラスでのみアクセスできます。背後では、.NETはデリゲートを保持するプライベートインスタンス変数を作成します。

コンパイラは、実際にはパブリックイベントとプライベートフィールドを作成しています。同じクラスまたはネストされたクラスから直接フィールドにアクセスできます。外部クラスからは、登録/登録解除のみが許可されます。

Jon Skeetからの素晴らしい情報は、なぜこれがどのように動作するのかについては、hereがあります。

+0

これは問題ではありません。宣言クラス内からイベント_is_にアクセスしようとしました... –

+0

@Nick:いいえ、これは何が起こっているかを絶対に言っています:フィールドのようなイベントの場合、イベントを呼び出すように見える呼び出しは、 。あなたはその知識をとり、それをカスタムイベントに適用します - バッキングフィールドを介して*それを呼び出すこともできます。 –

+0

@ジョン:エラーCS0079を理解するために、フィールドのようなイベントがどのように実装されているかを逆にすることができます。その答えが集中していたら、+1されて、私からやったでしょう。しかし、答えはフィールドのプライベートなアクセシビリティに焦点を当てています。それはそのポイントの横にあります。 –

2

イベントを発生させるには、手動で宣言されたバッキングデリゲートを呼び出す必要があります。MyEvent(null, EventArgs.Empty)_myEvent(null, EventArgs.Empty)に置き換えます。それについて考えると、カスタムの追加/削除はデリゲートをどこにでも格納することができます。なぜなら、それをあなたが書いた方法で取得して呼び出すことができないからです...

+0

:しかし、もし私がクラスを派生させ、サブクラスに基底のデリゲートフィールドを公開したくないのですか?それは混乱になるでしょう?私はちょうどサブクラスが基本クラスのイベントを発生させることが許されていないことを観察しました。このデザインはちょっと弱いですか?外部の人がそれを混乱させるのを防ぐために、イベントが採用されています。しかし、なぜ内部者も制限されていますか? – Need4Steed

+0

推奨されるパターンは、イベントを発生させる保護された仮想メソッドを提供することです。http://msdn.microsoft.com/en-us/library/ms229011.aspx –

+1

ありがとうございます。しかし、私はまだ、火に向けられていないデザインはかなり不自由だと思っています。イベントはバーチャルで、サブクラスによってオーバーライドされることもありますが、それらを起動するには、いくつかのヘルパー仮想メソッドに頼らざるを得ません。 – Need4Steed

関連する問題