26

EventArgsイベントを呼び出すクラスに情報を返す目的でイベントハンドラーを変更することは嫌われていますか?

たとえば、SSLの証明書を検証する必要がある低レベルの通信クラスがあるが、それはクラスのさまざまなユーザーの知識であるため、有効な証明書がどのように見えるかを知る方法がない場合です。

class ValidationEventArgs : System.EventArgs
{
    public X509Certificate Certificate { get; set; }
    public bool Valid { get; set; }
}

次に、オブジェクトを使用してイベントに接続し、Validフラグを変更して証明書が受け入れ可能かどうかを確認します。

comms.ValidationEvent += CertValidationHandler;
    
void CertValidationHandler(ValidationEventArgs args)
{
    if (args.Certificate.Issuer.Contains(COMPANY_NAME))
        args.Valid = true;
}

私はこのように使用されているという言及を見つけましEventArgsたが、それは推奨されないと言う人々も見ました。

編集:EventArgs多分私はこれが継承についてではなく、コミュニケーションの双方向チャネルとしてそれらを使用することについてであることを明確にする必要があります。他の人がコメントしたように、これは許容範囲であり、Googleが反対に拾うどんなノイズも、おそらく概念を誤解/誤用した人々であり、今ではと同じ個人的な十字軍を持っていgotoます。

4

3 に答える 3

44

「イベントをパブリッシュするときに、サブスクライバーに EventArgs 値のいずれかを変更してもらいたいですか?」という質問を自問してください。答えが「いいえ」の場合、たとえば読み取り専用の情報をブロードキャストしている場合は、クラスを不変にします。ただし、サブスクライバーからのフィードバックが必要な場合は、変更する必要があるプロパティを可変にします。

明確にするために、ブロードキャストの例では、サブスクライバーに何かを伝えたいが、値を変更させないようにしたいと考えています。

public class ProgressEventArgs : EventArgs
{
    public ProgressEventArgs(int current)
    {
        this.Current = current;
    }

    public int Current { get; private set; }
}

ただし、クラス自体が知らない情報を要求するイベントを発生させることもできます。

public class FeedbackEventArgs : EventArgs
{
    public bool ShouldContinue { get; set; }
    public string Reason { get; set; }
}
于 2012-02-16T08:53:27.863 に答える
10

ジェネリック型アプローチを通じて EventArgs クラスを使用できます。このサンプルでは、​​戻り値の型として Rect クラスを使用します。

public EventHandler<Rect> SizeRectChanged;

イベントの発生:

if(SizeRectChanged != null){
   Rect r = new Rect(0,0,0,0);
   SizeRectChanged(this,r);
}

イベントのリッスン:

anyElement.SizeRectChanged += OnSizeRectChanged;

public void OnSizeRectChanged(object sender, Rect e){
    //TODO abything using the Rect class
    e.Left = e.Top = e.Width = e.Height = 50;
}
于 2013-11-13T10:43:28.947 に答える
2

からの継承に対する推奨事項は認識していませんEventArgs。私の知る限り、それを継承することは良い習慣です。

一般原則として、派生クラスを不変にすることをお勧めします。これにより、必要に応じてスレッド間を安全に渡すことができます。これを行う最も簡単な方法は、プロパティを として宣言{ get; private set; }し、コンストラクターでのみ設定することです。明らかに、質問にある特定のユースケースではそれを行うことはできませんが、可能な場合は行う必要があります。

于 2012-02-16T08:20:36.357 に答える