Есть ли особая связь между классом EventArgs и ключевым словом события?

Во всей книге .NET, которую я прочитал, руководство по реализации событий объясняет, что вам нужно создать подкласс EventArgs и использовать EventHandler. Я нашел дополнительную информацию на http://msdn.microsoft.com/en-us/library/ms229011.aspx, и в нем говорится: «Используйте System.EventHandler вместо того, чтобы вручную создавать новые делегаты, которые будут использоваться в качестве обработчиков событий». Я понимаю, что есть важные причины для использования EventArgs, но мой вопрос не в том, «Должен ли я сделать это таким образом?», А в том, «Могу ли я сделать это таким образом?».

Есть ли причина, по которой я не могу использовать общий делегат вместо EventHandler с моими событиями? Например, если мне нужен строго типизированный отправитель (кого-то еще это раздражает object sender?).

Чтобы лучше объяснить, что я имею в виду, есть ли причина, по которой следующее не работает?

public class IoC
{
    public AbstractFactory GetAbstractFactory()
    {
        var factory = new AbstractFactory();
        factory.CreateObject += ()=>new object();
        return factory;
    }
}
public class AbstractFactory
{
    public event Func<object> CreateObject;

    private object OnObjectCreated()
    {
        if(CreateObject == null)
        {
            throw new Exception("Not injected.");
        }
        return CreateObject();
    }


    private object _injectedObject;
    public object InjectedObject
    {
        get
        {
            if(_injectedObject == null)
            {
                _injectedObject = OnObjectCreated();
            }
            return _injectedObject;
        }
    }
}

person smartcaveman    schedule 08.02.2011    source источник
comment
Я сделал именно это, чтобы реализовать что-то похожее на наблюдаемую коллекцию.   -  person asawyer    schedule 09.02.2011
comment
Связанная ветка: http://stackoverflow.com/questions/4828212/should-eventhandler-always-be-used-for-events/4828233   -  person CodesInChaos    schedule 09.02.2011


Ответы (3)


Это просто условность, а не требование языка. Вы можете использовать любой тип делегата в качестве события.

Однако стандартная подпись EventHandler<T> имеет несколько преимуществ:

  1. Вы можете расширить параметр EventArgs. Это не сработало бы, если бы у вас был один параметр для каждой вещи, которую вы хотите передать в обработчик событий.
  2. EventHandler, который принимает базовый класс EventArgs, может подписаться на любое событие в соответствии с соглашением.
  3. Вы можете добавить к EventHandler<T> методы расширения, которые появляются во всех событиях.
  4. Тип возврата - void. Другие возвращаемые типы не имеют особого смысла в качестве обработчиков событий.
  5. Вы следуете соглашению. Следование соглашению обычно является хорошей идеей, если у вас нет веских аргументов против этого.
person CodesInChaos    schedule 08.02.2011

Вся документация от Microsoft касается дизайна библиотек базовых классов и / или общих рекомендаций по проектированию фреймворка. Вы можете использовать любой узор, какой захотите.

Тем не менее, если люди будут использовать ваш код, он будет им более знаком, если вы будете следовать шаблонам, которые использует Microsoft.

person Chris Haas    schedule 08.02.2011

Насколько мне известно, EventHandler и EventArgs - лучшие практики, но ничто не мешает вам использовать произвольный делегат в объявлении события. Ключевое слово event дает вам особую функциональность, заключающуюся в возможности делегировать + = и - = в слот события, в отличие от простого наличия поля или свойства типа делегата, которые будут принимать только один делегат (если вы не составите несколько делегатов. себя).

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

person StarKat99    schedule 08.02.2011
comment
Возвращается последнее значение. Но это так же бесполезно. - person Henk Holterman; 09.02.2011