Я не могу расширить (подкласс) DataReceivedEventArgs?

#c# #events #controls

#c# #Мероприятия #элементы управления

Вопрос:

Я пытаюсь расширить DataReceivedEventArgs, чтобы я мог передавать дополнительные данные в класс, который расширяет процесс. В значительной степени, а не просто получать данные из процесса при подключении к процессу.OutputDataReceived, я хотел бы передать элемент управления для его записи.

При попытке расширить DataReceivedEventArgs я получаю ошибки:

 The type 'System.Diagnostics.DataReceivedEventArgs' has no constructors defined

public class DataReceivedArgsWithControl : DataReceivedEventArgs
{
    public Control ControlAdded { get; set; }
}
  

Как я могу добавить другое свойство к этим аргументам? Я расширил сам EventArgs, потому что у него есть конструктор, но не уверен, как расширить эти аргументы.

Комментарии:

1. Просто создайте свой собственный класс event и EventArgs, не нужно выводить.

2. Мне нужно свойство, которое предоставляется в DataReceivedEventArgs : public string Data { get; }

3. Да, это то, что вам понадобится для вашего собственного класса EventArgs, когда вы создаете свое собственное событие. Как это сделал Стив.

Ответ №1:

Я подозреваю, что вы не можете, потому что конструктор есть Internal . Возможно, лучшим подходом было бы обернуть DataReceivedEventArgs внутри вашего EventArgs производного класса.

 class MyDataReceivedEventArgs : EventArgs
{
   DataReceivedEventArgs _inner;

   public MyDataReceivedEventArgs(DataReceivedEventArgs inner, object extraProperty)
   {
      _inner = inner;
      ExtraProperty = extraProperty;
   }

   public object ExtraProperty { get; private set;}
   public DataReceivedEventArgs DataArgs  
   { 
     get
     {
        return _inner;
     }
   }
}
  

Конечно, это может не подойти, если вам нужен полиморфизм с. DataReceivedEventArgs Если у вас есть обработчик событий, который ожидает a DataReceivedEventArgs , то он не будет работать с классом-оболочкой. Например:

 public void MyHandler(object sender, DataReceivedEventArgs e) { ... }
  

Это может получить только DataReceivedEventArgs экземпляр или экземпляр производного типа, которым ваша оболочка не является. Так что это зависит от того, нужно ли вам обрабатывать ваш пользовательский класс EventArgs, если бы он был DataReceivedEventArgs где угодно.

Обновить-

Если вы не можете изменить подпись используемого вами делегата public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e) , вы все равно можете подписаться, используя метод с подписью void MyEventHandler(object sender, EventArgs e) благодаря контравариантности параметров делегата, а затем проверить фактический тип EventArgs параметра.

 public void MyEventHandler(object sender, EventArgs e)
{
   var dataEventArgs = e as MyDataReceivedEventArgs;

   if(dataEventArgs != null
   {
      var extendedProperty = dataEventArgs.ExtraProperty;
      var innerArgs = dataEventArgs.DataArgs;
   }
}
  

Идеальным вариантом было бы переопределить тип делегата в соответствии с вашей оболочкой, но описанный выше подход будет работать.

Комментарии:

1. Не могли бы вы немного подробнее объяснить свое последнее предложение? Я не уверен, что понимаю, где у меня могут возникнуть проблемы с использованием этого типа оболочки.

2. Спасибо за обновление, я думаю, что тогда это будет проблемой. Процесс. Событие OutputDataReceived ожидает обработчика DataReceivedEventHandler, который ожидает DataReceivedEventArgs: public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e) . Похоже, мне придется найти другой способ получить функциональность такого типа

3. Не обязательно. Если вы не можете переопределить делегат, вы можете воспользоваться ковариацией делегата, которая в данном случае не идеальна, но будет работать. Я обновлю ответ.

4. Я выполнил следующее и получил ошибки : process.OutputDataReceived = new MyEventHandler(TestMethod) . Подпись для метода тестирования: MyEventHandler(object sender, EventArgs e) . Ошибка гласит: Cannot convert type project.MyEventHandler to System.Diagnostics.DataReceivedEventHandler . Я что-то забыл?

5. Попробуйте вместо process.OutputDataReceived = TestMethod этого либо обработать. OutputDataReceived = новый DataReceivedEventHandler(метод тестирования)`