У .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; }
    }
}

Прежде чем я это сделаю, у С# есть такая же особенность, встроенная в язык? Кажется, я вспоминаю, что натолкнулся на что-то подобное, когда вышел С# 2.0, но теперь я не могу его найти.

Или, говоря иначе, мне нужно создать свой собственный общий класс EventArgs, или С# предоставить его? Благодарим за помощь.

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

Если вы решите не использовать Призма, но все же хотите попробовать общий 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
};

Ответ 5

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

Ответ 6

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

Ответ 7

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

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