2009-04-02 6 views
15

eventOne(キーワード 'event')とeventTwo(w/oキーワード)の違いは何ですか?キーワード 'event'はC#ではオプションですか?

class Program 
{ 
    public event EventHandler eventOne; 
    public EventHandler eventTwo; 

    public void RaiseOne() 
    { 
     if (eventOne != null) 
      eventOne(this, EventArgs.Empty); 
    } 

    public void RaiseTwo() 
    { 
     if (eventTwo != null) 
      eventTwo(this, EventArgs.Empty); 
    } 

    static void Main(string[] args) 
    { 
     var p = new Program(); 
     p.eventOne += (s, e) => Console.WriteLine("One"); 
     p.eventTwo += (s, e) => Console.WriteLine("Two"); 
     p.RaiseOne(); 
     p.RaiseTwo(); 
    } 
} 

答えて

20
  • eventOne公共イベントですタイプEventHandlerの民間分野に裏打ちされました。
  • eventTwoは、EventHandlerフィールドの公開です。

のみは「購読」とプロパティは、「取得」および「設定」のではなく、実際のストレージのアイデアをカプセル化するのと同じように「退会」のアイデアをカプセル化基本的イベント。 (CLRに関する限り、イベントは「引き上げ」メソッドを公開することもできますが、C#ではこれを使用しません)無視してください)

代理人とイベントの違いの詳細についてはmy article on eventsを参照してください(alternate link)。あなたがC#、あなたの根本的なデリゲートのために、隠された方法に発生行くadd_XXXremove_XXX伝えるイベントキーワードを使用することにより

+0

前の答えはあなたが実際にILを見たことがあり考慮して、違いを説明するためのプログラムでありますか?あなたは驚かれるでしょう。 – Prankster

+0

はい、あります。何があなたを驚かせた? –

+0

'add'と 'remove'が実際に生成されている間、コンパイラはそれらを最適化しました。したがって、上記のコードでは、代理人のアクセス修飾子だけが違います。 – Prankster

16

。これにより、クラスを使用するすべてのユーザーは、イベントへの代理人の添付と削除のみが可能になります。重要な点は、クラス外の誰もがイベントを起こさないということです。だからこのことがいつ起きるかを完全に制御できます。

イベントを使用していない場合は、誰でも追加、削除、呼び出しができる公開デリゲートを公開するだけです。あなたのクラス以外の誰かが呼び出すことを望むことはほとんどありません。

+0

Pranksterのコードに明らかな違いがないのは、eventOneとeventTwoのすべてのアクションが同じクラス内で実行されたためです。異なるクラスからそれらにアクセスしたコードは、その違いを説明するでしょうか? –

8

これは

using System; 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var a = new A(); 
     a.eventOne += (s, e) => Console.WriteLine("One"); 
     a.eventTwo += (s, e) => Console.WriteLine("Two"); 
     a.RaiseOne(); 
     a.RaiseTwo(); 
       // won't compile 
     a.eventOne(null, EventArgs.Empty); 
     a.eventTwo(null, EventArgs.Empty); 
    } 

} 

class A { 
    public event EventHandler eventOne; 
    public EventHandler eventTwo; 

    public void RaiseOne() 
    { 
     if (eventOne != null) 
      eventOne(this, EventArgs.Empty); 
    } 

    public void RaiseTwo() 
    { 
     if (eventTwo != null) 
      eventTwo(this, EventArgs.Empty); 
    } 
}