2016-07-09 14 views
2

VS 2015で遊んでいる間、私はプロパティを作成していましたが、タブを押す前にミスタイプしていて、イベントを作成するための非常にきれいな簡単な方法です。私はデータを渡すために追加のパラメータを受け入れるためにこれをどのように使用するのか不明です(何が進行中であるか、何が行われたのかに関する情報をイベントに呼び出すときにデータを渡したいので)クラスでイベントを作成する最も簡単な方法

コードは

一見、ほとんどの例と似ていますが、このメソッドはデリゲートを操作する必要はありません。私はよりエレガントな(きれいな)コードを持つの光の中で、知っていただきたいと思い何How to call an event manually in C#?

public delegate void MyEventHandler(object sender, MyEventArgs e) 
public event MyEventHandler MyEvent; 
public void RaisesMyEvent() 
{ 
    if(MyEvent != null) //required in C# to ensure a handler is attached 
     MyEvent(this, new MyEventArgs(/*any info you want handlers to have*/)); 
} 

から、次の例と比較し、Microsoftが(この質問の最初の方法)を良く提供される方法がある(それはきれいらしいです)、もしそうなら、私は標準的なイベント引数に加えて文字列を受け入れるか、あるいは情報を渡すためにeventargsを拡張するためにそれを少し調整することができますか?

+2

@VisualVincentカスタムのEventArgsを使用するためにカスタムデリゲートは必要ありません。その目的のために汎用的な 'EventHandler 'があります。 –

+0

@ThomasLevesque:ああ、私は実際にそれを知らなかった。ありがとう、知って良いこと! –

+0

@ThomasLevesque - あなたはこれの例を挙げることができますか? TEeventArgsに基づいて新しいオブジェクトを作成しようとすると、その名前でプロパティを作成するように私に要求するエラーが表示されます(別名、存在しないようです)。 –

答えて

1

、あなたがEventArgsから派生し、独自のクラスを作成し、そのような宣言を変更します:あなたはあなたのハンドラ内object senderを持っ好きではない場合、あなたの代わりに

public event EventHandler<MyCustomEventArgs> MyEvent; 

を行うことができます。

public event Action<MyCustomEventArgs> MyEvent; 

あるいは

public event Action<string> MyEvent; 

呼び出しに関しては、Microsoftの方が優れています。理由は、あなたが書いたヌルチェックはスレッドセーフではないということです。 nullチェックを行う前にハンドラを保存しておくと、nullメソッドを呼び出さないことが保証されます。また

、C#6呼び出しを使用し、null条件演算子を活用する:ちょうどあなた自身のクラスにEventArgsを置き換える

MyEvent?.Invoke(whateverArgs); 
+0

非常に有益です。ありがとうございました。 –

1

のVisual Studioあなたのための自動生成されるコードは、実際には1つの小さな条件のためのより良いです:

public void RaisesMyEvent() 
{ 
    if(MyEvent != null) //required in C# to ensure a handler is attached 
     // Now if someone in another thread sets MyEvent to null the next line will still execute 
     MyEvent(this, new MyEventArgs(/*any info you want handlers to have*/)); 
     // And throw a NullReferenceException 
} 

このコードでは、競合状態を持っています。ヒットするのはかなり稀ですが、可能です。 Visual Studioの定型コードは、イベントハンドラを呼び出す前にローカルのコピーを作成することによって、この競合状態を回避します。イベントハンドラに複数のパラメータを渡す方法については

あり、複数の方法がありますが、「標準的な」方法がいるEventArgsを拡張するクラスを作成することです。例えば、PaintEventArgsEventArgsに拡張され、OnPaintハンドラが使用するためにはGraphicsRectangleのプロパティが追加されます。

EventArgsに基づいてMyEventArgsクラスを作成し、そのメソッドで使用する必要があるプロパティを追加することで、その基本パターンに従います。 EventHandlerにカスタム引数を渡すために

+0

この回答には感謝します。非常に有益。 –

1

class MyEventArgs : EventArgs 
{ 
    public string Text { get; private set; } 

    public MyEventArgs(string text) 
    { 
     Text = text; 
    } 
} 

EventHandler<T>ジェネリックデリゲート型はEventArgsかを受け入れますEventArgsのサブクラスです。

OnMyEvent()を呼び出すと、イベントで配信するデータを含むクラスのインスタンスを渡すだけです。

スレッドセーフな呼び出しに関するその他の注意事項に同意します。これは必ずしも必要なわけではありませんが、実装が簡単で、IDE提供のバージョンは安全ではありません。

+0

これは、制御されたユニバーサルアプリケーションが構造化データを渡すのに便利です。他のプロパティを追加することももちろん可能です。私はこれに脳のおならがあったと思いますが、単純に 'EventHandler 'の代わりに 'EventHandler 'を使います。 –

関連する問題