web-dev-qa-db-ja.com

.NETには組み込みのEventArgs <T>がありますか?

単一の引数を持つイベント引数用の汎用EventArgsクラスを作成する準備ができています。

public class EventArg<T> : EventArgs
{
    // Property variable
    private readonly T p_EventData;

    // Constructor
    public EventArg(T data)
    {
        p_EventData = data;
    }

    // Property for EventArgs argument
    public T Data
    {
        get { return p_EventData; }
    }
}

その前に、C#には同じ機能が言語に組み込まれていますか? C#2.0が登場したとき、そのようなものに出くわしたことを思い出すようですが、今では見つけることができません。

別の言い方をすれば、独自の汎用EventArgsクラスを作成する必要がありますか、それともC#で提供されますか?ご協力いただきありがとうございます。

81
David Veeneman

いいえ。おそらく EventHandler<T> 。これにより、特定タイプのEventArgsのデリゲートを定義できます。

個人的にはEventArgs<T>とはいえ、かなり適合しています。イベント引数で「ペイロード」として使用される情報は、私の意見では、使用法と期待されるプロパティを非常に明確にするためのカスタムクラスである必要があります。ジェネリッククラスを使用すると、意味のある名前を適切な場所に配置できなくなります。 (「データ」は何を表していますか?)

63
Reed Copsey

ここですべての「純粋主義者」を理解していないと言わなければなりません。つまり、バッグクラスが既に定義されている場合-これにはすべての詳細、プロパティなどがあります-なぜイベント/引数メカニズム、署名スタイルに従うことができるように、ハックが余分な不要なクラスを作成するのですか?事は-.NETにあるすべてのものではない-またはその問題で「欠落」-「良い」-MSは何年もの間それ自体を「修正」している... -私はそのようにそれを必要としていたので-私は多くの時間を節約しました、

30
NSGaga

存在します。少なくとも、今はそうです。

発見できる - DataEventArgs<TData> いくつかの異なるMicrosoftアセンブリ/名前空間で、たとえば Microsoft.Practices.Prism.Events 。ただし、これらは名前空間であり、プロジェクトに含めるのが自然ではないため、独自の実装を使用するだけです。

9
Ulf Åkerstedt

Prism を使用しないことを選択したが、それでも一般的なEventArgsアプローチを試してみたい場合。

public class GenericEventArgs<T> : EventArgs
{
    public T EventData { get; private set; }

    public GenericEventArgs(T EventData)
    {
        this.EventData = EventData;
    }
}

//次のサンプルコードを使用してObjAdded eventを宣言します

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded;

//次のサンプルコードを使用して、ObjAddedイベントを発生させます

private void OnObjAdded(TargetObjType TargetObj)
{
    if (ObjAdded!= null)
    {
        ObjAdded.Invoke(this, new GenericEventArgs<TargetObjType>(TargetObj));
    }
}

//そして最後にObjAddedイベントをサブスクライブできます

SubscriberObj.ObjAdded +=  (object sender, GenericEventArgs<TargetObjType> e) =>
{
    // Here you can explore your e.EventData properties
};
6
Julio Nobre

そこにIS NO BUILT-IN GENERICARGS。MicrosoftEventHandlerパターンに従う場合、提案されたように派生したEventArgsを実装します:public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }

ただし、チームスタイルガイドが簡素化を受け入れた場合、プロジェクトは次のような軽量イベントを使用できます。

public event Action<object, string> MyStringChanged;

使用法 :

// How to rise
private void OnMyStringChanged(string e)
{
    Action<object, string> handler = MyStringChanged;    // thread safeness
    if (handler != null)
    {
        handler(this, e);
    }
}

// How to handle
myObject.MyStringChanged += (sender, e) => Console.WriteLine(e);

通常、PoCプロジェクトは後者のアプローチを使用します。ただし、プロのアプリケーションでは、FX警察の正当化#CA1009に注意してください。 https://msdn.Microsoft.com/en-us/library/ms182133.aspx

3
epox

ジェネリック型の問題は、DerivedTypeがBaseTypeを継承しても、EventArgs(DerivedType)がEventArgs(BaseType)を継承しないことです。したがって、EventArgs(BaseType)を使用すると、後で派生型を使用できなくなります。

1
supercat