Есть ли в .NET встроенные EventArgs <T>? - PullRequest
81 голосов
/ 22 июля 2010

Я готовлюсь к созданию универсального класса 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 # предоставляет его? Спасибо за вашу помощь.

Ответы [ 7 ]

63 голосов
/ 22 июля 2010

Нет. Вы, вероятно, думали о EventHandler<T>, который позволяет вам определить делегата для любого конкретного типа EventArgs.

Лично я не чувствую, что EventArgs<T> вполне подходит. На мой взгляд, информация, используемая в качестве «полезной нагрузки» в аргументах события, должна быть пользовательским классом, чтобы его использование и ожидаемые свойства были очень понятными. Использование универсального класса не даст вам возможности поставить значимые имена на место. (Что представляет собой «Данные»?)

30 голосов
/ 01 ноября 2010

Должен сказать, что я не понимаю всех «пуристов» здесь.т. е. если у вас уже определен класс bag - который имеет все особенности, свойства и т. д. - зачем хаку создавать один дополнительный ненужный класс, чтобы иметь возможность следовать механизму события / аргумента, стилю подписи?Дело в том, что не все, что есть в .NET - или «отсутствует» в этом отношении, - «хорошо» - MS годами «исправляла» себя ... Я бы сказала, просто пойти и создать ее - как я это сделала- потому что я нуждался в этом просто так - и сэкономил мне много времени,

9 голосов
/ 09 апреля 2013

Это существует. По крайней мере, сейчас.

Вы можете найти DataEventArgs<TData> в некоторых различных сборках / пространствах имен Microsoft, например Microsoft.Practices.Prism.Events . Однако это пространства имен, которые вы, возможно, не найдете естественными для включения в свой проект, поэтому вы можете просто использовать собственную реализацию.

6 голосов
/ 28 октября 2014

Если вы решите не использовать 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
};
3 голосов
/ 13 января 2016

ВСТРОЕННЫХ ОБЩИХ АРГОВ НЕТ.Если вы следуете шаблону 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

1 голос
/ 23 июля 2010

Проблема с универсальным типом заключается в том, что даже если DerivedType наследует от BaseType, EventArgs (DerivedType) не наследуется от EventArgs (BaseType). Таким образом, использование EventArgs (BaseType) предотвратит последующее использование производной версии типа.

0 голосов
/ 22 июля 2010

Причина, по которой этого не существует, заключается в том, что в конечном итоге вы реализуете это, а затем, когда вы идете, чтобы заполнить T, вы должны создать класс со строго типизированными однозначными свойствами, который будет действовать как пакет данных для вашего события. arg, но наполовину реализовав это, вы понимаете, что нет никаких причин, по которым вы не просто заставляете этот класс наследовать от EventArgs и называете его хорошим.

Если вам не нужна строка или что-то похожее базовое для вашей сумки данных, в этом случае, вероятно, в .NET существуют классы классов EventArgs, которые предназначены для выполнения любой простой задачи, к которой вы стремитесь.

...