Обработчики событий, существующий класс для нового интерфейса - PullRequest
0 голосов
/ 06 сентября 2011

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

Существующий класс

public class ClassA
{
    #region Events
    public delegate void DataReceivedHandler(object sender, EventArgs e);
    public delegate void DataSentHandler(object sender, EventArgs e);
    public delegate void StatusUpdatedHandler(object sender, EventArgs e);
    public event DataReceivedHandler DataReceived;
    public event DataSentHandler DataSent;
    public event StatusUpdatedHandler StatusUpdated;
    #endregion

    //rest of code here...
 }

Новый интерфейс

public interface IClassA
{
    event EventHandler DataReceived;
    event EventHandler DataSent;
    event EventHandler StatusUpdated;

    //rest of code here...
}

Мои три вопроса следующие.

Q1. Прав ли я, во-первых, объявлять своих собственных делегатов в классе, т.е. public delegate void DataReceivedHandler, или они должны быть удалены, а события заменены обычным EventHandler. т.е. public event EventHandler DataReceived. Учитывая, что эти события не передают данные вместе с событием, просто уведомляют все, кто подписан, что-то изменилось.

Q2. Тесно связан с вопросом выше. Учитывая, что я изменяю свойства класса, то есть статус (StatusUpdated). Рекомендуется ли передавать новое состояние как пользовательские EventArgs, что требует специального делегата, как в исходном коде? Поскольку это в настоящее время работает, событие инициируется, и подписанный класс может просто использовать значение отправителя, то есть (отправитель как ClassA) .Status. Есть ли лучшая практика или дело только за разработчиком?

Q3. Теперь это не так. Часть об интерфейсе. Правильно ли я объявил DataReceived и другие события в интерфейсе для соответствия классу, который будет помечен как реализующий его.

Ответы [ 2 ]

1 голос
/ 06 сентября 2011

В ответ на ваши вопросы, конечно, это вопрос мнения, поэтому я дам свои:

A1) Нет, вы не вправе повторно объявлять своих собственных XXXHandler делегатов, в структуре есть один (EventHandler), точно совпадающий с вашим - хороший признак того, что вы "заново изобретаете колесо" .

A2) Я считаю, что событие с именем StatusChanged должно передать новый (и, возможно, старый) статус любому подписчику. Однако это еще не повод для реализации вашего собственного делегата, так как фреймворк определяет универсальный делегат (EventHandler<TEventArgs>) именно для этой цели.

A3) В настоящий момент события вашего класса не соответствуют интерфейсу, это означает, что он не сможет реализовать его без изменений.

Документы: EventHandler<TEventArgs>

1 голос
/ 06 сентября 2011

Если вам нужны пользовательские делегаты для методов интерфейса, вы должны объявить их отдельно (вне класса), потому что они не привязаны к конкретной реализации.Объявление делегата может находиться внутри интерфейса, как и класс.Проблема с вашими делегатами заключается в том, что все они имеют одинаковую подпись (подпись EventHandler) и поэтому являются избыточными.

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

В-третьих, сигнатуры событий вашего интерфейса должнысоответствия класса подписи.Вы не можете использовать тип делегата EventHandler в интерфейсе и изменять сигнатуру внутри класса.

Обратите внимание, что вы также можете избежать явного объявления типов делегатов и использовать универсальные делегаты Action, предоставляемые с BCL (начиная с .NET 3.5).В этом случае у вас может быть что-то вроде:

public interface IClassA
{
   event Action<IClassA, Data> DataReceived;
   event Action<IClassA, Data> DataSent;
   event Action<IClassA, Status> StatusUpdated;
}

Последний подход дает вам преимущество наличия строго типизированного параметра sender (в отличие от object в EventHandler).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...