2011-08-12 22 views
14

私はちょうど静的イベントが存在することを認識しました - そして、私は人々がそれらをどのように使用するのか不思議です。私は相対比較が静的メソッドとインスタンスメソッドにどのように影響するのだろうかと思います。たとえば、静的メソッドは基本的にグローバル関数です。しかし、私はいつもイベントをのオブジェクトのインスタンスに関連付けていましたが、私はそれらをグローバルレベルで考えるのに問題があります。ここでC#で静的イベントと非静的イベントを比較するにはどうすればよいですか?

それは説明を助けている場合を参照するためにいくつかのコード:

void Main() 
{ 
    var c1 = new C1(); 
    c1.E1 +=() => Console.WriteLine ("E1"); 
    C1.E2 +=() => Console.WriteLine ("E2"); 
    c1.F1(); 
} 

// <<delegate>>+D() 
public delegate void D(); 

// +<<event>>E1 
// +<<class>><<event>>E2 
// +F() 
//  <<does>> 
//   <<fire>>E1 
//   <<fire>>E2 
public class C1 
{ 
    public void F1() 
    { 
     OnE1(); 
     OnE2(); 
    } 
    public event D E1; 
    private void OnE1() 
    { 
     if(E1 != null) 
     { 
      E1(); 
     } 
    } 
    static public event D E2; 
    static private void OnE2() 
    { 
     if(E2 != null) 
     { 
      E2(); 
     } 
    } 
} 

答えて

14

多くのOOPは、メッセージの受け渡しに関して考えることができます。

メソッド呼び出しは、呼び出し元から呼び出し元(パラメータを含む)へのメッセージであり、戻り値を持つメッセージです。

イベントは、送信元からサブスクライバへのメッセージです。したがって、潜在的に2つのインスタンスが関与し、メッセージを送信するインスタンスとそれを受信するインスタンスが存在する。

静的イベントの場合、送信インスタンスはありません(クラスのみである場合もありません)。デリゲートのターゲットとしてエンコードされた受信者インスタンスは依然として存在する可能性があります。

1

静的メンバーではない、「グローバル、」彼らは単にクラスのではなく、クラスインスタンスのメンバーです。

静的イベントを使用する例はありません。ほとんどの場合、静的メンバーを見つけるのが一般的ではないためです。 (彼らはシングルトンのように、アンチパターンを示唆する傾向がある。)の場合

+0

このように、サブスクライバのリストはクラスレベルにも正しく設定されていますか?同時に購読している複数のスレッドが悪いことにつながるのでしょうか? –

+0

静的イベントのデフォルトの実装では、 'Interlocked.CompareExchange'が使用されます。これは、レースの場合、スレッドの1つがサブスクライブされないことを意味します。 – cdhowie

+0

@cdhowie:それは 'Interlocked.CompareExchange'の非常にばかげた使い方です。通常、比較とスワップはリトライループとペアになっています。 –

3

あなたはおそらくすでに静的メソッドに精通している静的メソッド

に慣れていません。そうでない場合は、静的メソッドを使用するためにオブジェクトのインスタンスを作成する必要はありませんが、オブジェクトのインスタンスを作成して非静的メソッドを呼び出す必要があります。静的メソッド。

良い例は、System.IO.DirectoryクラスとSystem.IO.DirectoryInfoクラスです。

Directoryクラスは静的メソッドを提供しますが、DirectoryInfoクラスは静的メソッドを提供しません。

あなた自身の違いを見るためにここに2つの記事があります。静的イベントに今の

http://visualcsharptutorials.com/2011/01/system-io-directory-class/

http://visualcsharptutorials.com/2011/01/system-io-directoryinfo-class/

...

はしかし、静的なイベントはめったに野生で見られません。私がopfを実際に使いたいと思うケースはごくわずかですが、潜在的な使用方法を示すCodeProjectの記事があります。

http://www.codeproject.com/KB/cs/staticevent.aspx

ここで重要な思考が(関連するテキストを指摘するために私が追加したボールド)の説明から取られる:

我々は個別のオブジェクトとして、このプロパティを見て、私たちはそのことを確認しました は、一度に1つのインスタンスに過ぎません。 のトランザクションのすべてのインスタンスは、必要なときにトランザクションを見つける場所を知っていました。しかし、細かい の違いがあります。トランザクションは、 の値を要求することによって、その時点で変更された最後の 変更された値を使用するのではなく、為替レートの変化を知る必要はありません。 のように、 のようにフォントのようなUI特性の の変更にユーザインターフェイスが直ちに反応する アプリケーションを実装したい場合など、これでは不十分です。フォントクラスにstaticFlashの があり、その値を という静的メソッドですべてのインスタンスに変更すると、非常に簡単になります。 の外観を更新する必要があるときに通知します。

.NET開発者は、切断されたモデルで作業するように訓練されています。従来のADOと比較してADO.NETを考えてみましょう。 VB6アプリケーションでは、次の機能を可能にするデータコントロールを使用することができます。PCでアプリケーションを実行していた場合、別のPCの誰かがデータを編集したときにグリッドのデータが更新されます。

これは、.NET開発者が慣れていたものではありません。私たちは、切断されたモデルに慣れています。 静的イベントにより、より "接続された"エクスペリエンスが実現します。 (その経験は、私たちがこれ以上に慣れていない何かである場合も同様です。)いくつかの洞察力のための

+0

詳細と参考文献のおかげです。 –

2

は、このリンクをチェックhttp://www.codeproject.com/KB/cs/staticevent.aspx

インスタンスが を存在しない場合に

静的イベントは

  • 使用することができます
  • 既存のすべてのインスタンスに対していくつかのマルチキャストイベントを実行するには...
  • イベントを発生させる静的クラスがある場合...

しかし、一つは議論http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/2ac862f346b24a15/8420fbd9294ab12a%238420fbd9294ab12a?sa=X&oi=groupsr&start=1&num=2

詳細

http://msdn.microsoft.com/en-us/library/8627sbea.aspx
http://dylanbeattie.blogspot.com/2008/05/firing-static-events-from-instance.html
http://www.nivisec.com/2008/09/static-events-dont-release.html

45

は、静的なイベントを警戒してご覧ください... cuationでそれらを使用する必要があります。オブジェクトがイベントにサブスクライブすると、そのオブジェクトへの参照がイベントのパブリッシャによって保持されることに注意してください。つまり、静的イベントが永久に生き残るようにする、つまり管理されたメモリリークに相当するものになる可能性があるため、静的イベントを明示的に拒否することに非常に注意する必要があります。

+0

おかげさまでありがとう - ありがとう –

+2

良い点。しかし、場合によってはこれは問題ではないかもしれません。場合によっては、ハンドラも静的にすることができます。それとも、シングルトンに住んでいるかもしれません。 –

+4

@TheDag:確かに、またはアプリケーションが存続している間、登録されているオブジェクトが存在することがあります。問題は、この静的イベントに登録するたびに*これを考える*必要があることです。精神的なオーバーヘッドが加わり、誰もが何が起こっているのか分かりません。 –

関連する問題