Does.NET есть встроенный EventArgs?


Я готовлюсь создать общий класс 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 78

7 ответов:

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

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

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

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

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

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

// и finnaly вы можете подписаться на ваш ObjAdded событие

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

НЕТ ВСТРОЕННЫХ ОБЩИХ АРГУМЕНТОВ. Если вы следуете шаблону 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 cop justification #CA1009: https://msdn.microsoft.com/en-us/library/ms182133.aspx

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

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

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