Параметр события; "отправитель как объект" или "отправитель как Т"?
Когда я пишу публичные события для своих бизнес-объектов, я адаптировал привычку всегда передавать экземпляр как " отправитель как Object", в дополнение к дополнительным конкретным параметрам. Я просто спросил себя сейчас почему я не указываю класс?
Итак, для вас больше опыта; Вы когда-нибудь проходили отдельный класс в качестве отправителя в событии? И если да, каковы ваши критерии решения, если это нормально/не нормально?
Ответы
Ответ 1
Не будь экстремальным. EventHandler(object sender, EventArgs e)
имеет отправителя объекта, чтобы мы могли использовать его во многих случаях. Но это не означает, что строго типизированный отправитель является злым. Сильно типизированный отправитель полезен, когда этот делегат не будет широко использоваться (например, EventHandler
), например.
public delegate void SaveHandler(Controller sender, EventArgs e);
Теперь другие разработчики (или кто-то, кто использует вашу библиотеку) могут регагонировать, что отправитель должен быть Controller
, и они будут рады, что не будут писать код следующим образом:
public void MySaveHandler(object sender, EventArgs arg)
{
var controller = sender as Controller;
if (controller != null)
{
//do something
}
else
{
//throw an exception at runtime?
//It can be avoided if sender is strongly-typed
}
}
И вы даже можете сделать его общим:
public delegate void SaveHandler<T>(T sender, EventArgs args)
where T: IController;
Это чистая юридическая и хорошая практика в С#. Вы должны четко указать, что вы хотите сделать, а затем выбрать лучший способ. Любой из них злой/плохой.
Ответ 2
Существует руководство по дизайну, в котором указано, что обработчик событий должен иметь два параметра: отправитель (объект) и e (EventArgs или производные от этого).
Ответ 3
Нет такого ограничения. Это всего лишь руководство, которое соблюдается в BCL (Base Class Library) и других популярных средах.
Я бы порекомендовал вам следовать ему, чтобы он был последовательным, если он будет использоваться другими разработчиками или будет выпущен в качестве рамки.
Ответ 4
Насколько я вижу, вы можете либо создать делегатов с нужными параметрами, а затем создать событие с помощью этого делегата, а затем вы можете вызвать событие и передать параметры в или использовать пользовательский аргумент события, как показано на рисунке здесь. Как показывает другой ответ. Держите его согласованным.
Не отвечает на ваш вопрос о критериях принятия решений, но надеюсь, что это поможет
Ответ 5
Моя нынешняя философия заключается в том, чтобы как можно ближе использовать стандартный метод Microsoft. Из этого вы получаете две вещи:
- Новые разработчики могут быстро понять ваш код.
- Вы тренируете существующих разработчиков, как работает остальная часть структуры.
Ответ 6
Хорошо использовать подпись object sender, EventArgs e
, так как метод может обрабатывать любые события этой подписи. Например, в проекте с использованием элемента управления диаграммами существует несколько типов событий MouseOver
- от DataSeries
, от легенды, от всего холста.
Таким образом, вы можете обрабатывать любой источник события, так как в большинстве случаев информация находится в EventArgs
.
Кроме того, вам не нужно передавать отправителя при передаче его делегату, так как любой экземпляр класса является объектом в глубине.
Ответ 7
Было много дискуссий по связанному вопросу о StackOverflow некоторое время назад. Вот этот вопрос: Подпись к событию в .NET. Использование синтаксического отправителя
В конце концов, это сводится к предпочтению. В большинстве случаев вы хотите, чтобы ваши обработчики событий были привязаны к определенному типу класса, поэтому превращение отправителя в объект, а затем возврат к классу, чтобы получить доступ к его свойствам, может не совпадать с вами [это для меня тоже не подходит).
Кроме того, с .NET 3+ и введением ковариации делегатов и контравариантности, не должно быть проблемой использовать строго типизированный делегат. Должен признаться, я использовал сильно типизированные обработчики событий несколько раз в своем коде.
Как я уже говорил, это зависит от предпочтений; Microsoft только что выпустила набор строк guide не правил...
Ответ 8
Это не обязательная для вас такая реализация. Обычно это делается из-за EventHandler
делегат, с таким прототипом.
Его простая рекомендация, за которой следует библиотека базового класса. Но убедитесь, что вы можете создать собственные параметры и реализации.
Но помните, если он будет использоваться другим разработчиком, который вам, он должен знать о такой реализации. Его дон для большей пользы и гибкости для использования события в любом месте, независимо от того, какой класс он использовал.
Если вы определяете Пользовательский прототип для события, я бы предположил, что вы также определяете Пользовательский делегат, который гарантирует, что вы поймаете исключение если соответствующий тип не передан. (При необходимости пользователю необходимо выполнить Явное приведение)
Вот так:
public delegate void MyEventHandler( MyType sender, EventArgs e);
Затем используйте его, если необходимо, в качестве:
this.MyEvent += new MyEventHandler(my_eventhandlerfunction);