Есть ли особая связь между классом EventArgs и ключевым словом event? - PullRequest
5 голосов
/ 09 февраля 2011

Во всей книге .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;
        }
    }
}

Ответы [ 3 ]

6 голосов
/ 09 февраля 2011

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

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

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

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

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

0 голосов
/ 09 февраля 2011

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

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

...