89

単一の引数を持つイベント引数用のジェネリック 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# で提供されているのでしょうか? ご協力いただきありがとうございます。

4

7 に答える 7

70

いいえ。おそらくEventHandler<T>、特定のタイプのEventArgsのデリゲートを定義できるようにすることを考えていたでしょう。

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

于 2010-07-22T18:34:33.340 に答える
34

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

于 2010-10-31T23:08:09.733 に答える
10

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

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

于 2013-04-09T08:18:32.423 に答える
8

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

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

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

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

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
};
于 2014-10-28T01:18:52.760 に答える
4

組み込みの汎用引数はありません。Microsoft EventHandler パターンに従う場合は、派生した 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に注意してください。

于 2016-01-13T10:05:25.383 に答える
1

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

于 2010-07-22T21:01:49.980 に答える
-4

これが存在しない理由は、これを実装するとどうなるかということです。その後、T を入力するときに、イベント引数のデータ バッグとして機能する、厳密に型指定された明確なプロパティを持つクラスを作成する必要がありますが、実装の途中で、そのクラスを EventArgs から継承させて、それを良いと呼ばない理由がないことに気付きました。

データバッグに文字列または同様の基本的なものが必要な場合を除き、その場合、.NETには標準のEventArgsクラスがあり、取得している単純な目的を果たすことを目的としています。

于 2010-07-22T19:34:40.363 に答える