Как добавить делегата в интерфейс C # - PullRequest
77 голосов
/ 16 октября 2010

Мне нужно, чтобы в моем классе было несколько делегатов.

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

Как?

Мой класс выглядит так:

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event UpdateStatusEventHandler UpdateStatusText;
    public delegate void UpdateStatusEventHandler(string Status);

    public event StartedEventHandler Started;
    public delegate void StartedEventHandler();
}

Мне нужен интерфейс, чтобы заставить этих делегатов:

public interface myInterface
{
   // ?????
}

Ответы [ 6 ]

126 голосов
/ 16 октября 2010

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

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{       
    event UpdateStatusEventHandler StatusUpdated;    
    event StartedEventHandler Started;
}

Реализация не будет (и не должна) повторно объявлять тип делегата, болеепереопределит любой другой тип, используемый в интерфейсе.

27 голосов
/ 28 августа 2012

Начиная с .NET 3.5 вы также можете использовать делегаты System.Action, что приведет к следующему интерфейсу:

public class ClsPictures : myInterface
{       
   // Implementing the IProcess interface
   public event Action<String> UpdateStatusText;

   public event Action Started;
}
7 голосов
/ 13 января 2017

Просто выставьте делегата как свойство

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{       
    UpdateStatusEventHandler StatusUpdated {get; set;}    
    StartedEventHandler Started {get; set;}
}
7 голосов
/ 16 октября 2010

Ответ Джона Скита верный, я просто хочу добавить примечание.

Нет интерфейсов для напоминания вам, что делать или что включать в ваши классы.Интерфейсы - это средства абстракции, используемые в объектно-ориентированном программировании и методах проектирования.Возможно, вам вообще не нужно объявление интерфейса, если вы не хотите видеть некоторые конкретные экземпляры классов в качестве интерфейса в другом месте вашей программы (Абстракция).

Если вы хотите применить некоторые стандарты кодирования в своем проекте,Вы можете попробовать использовать инструменты анализа кода (как в Visual Studio) - они позволяют расширения, которые вы можете включить, чтобы добавить свои собственные правила анализа кода.

Использование анализа кода, если вы «забыли» добавитьделегаты (хотя я не вижу смысла забывать об этом, как будто делегат не используется, он не нужен), вы получите предупреждение / ошибку.

1 голос
/ 10 марта 2016

В одном из ваших комментариев упоминается тип возвращаемого обработчика событий. Вас больше волнует тип обработчика или данные, возвращаемые из события? Если это последнее, то это может помочь. Если нет, то этого решения будет недостаточно, но оно может помочь вам приблизиться к тому, что вы ищете.

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

Ваш конкретный класс будет выглядеть так:

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
    //no need for this anymore: public delegate void UpdateStatusEventHandler(string Status);

    public event EventHandler<StartedEventArgs> Started;
    //no need for this anymore: public delegate void StartedEventHandler();
}

Ваш интерфейс будет выглядеть так:

public interface myInterface
{
   event EventHandler<StartedEventArgs> Started;
   event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
}

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

Для справки: https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx

0 голосов
/ 16 ноября 2015

Интерфейс, унаследованный в вашем производном классе, напомнит вам определить и связать материал, который вы объявили в нем.

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

Например, используя шаблон Inversion of Control:

class Form1 : Form, IForm {
   public Form1() {
     Controls.Add(new Foo(this));
   }

   // Required to be defined here.
   void IForm.Button_OnClick(object sender, EventArgs e) {
     ...
     // Cast qualifier expression to 'IForm' assuming you added a property for StatusBar.
     //((IForm) this).StatusBar.Text = $"Button clicked: ({e.RowIndex}, {e.SubItem}, {e.Model})";
   }
 }

Вы можете попробовать что-то вроде этого.

interface IForm {
  void Button_OnClick(object sender, EventArgs e);
}


class Foo : UserControl {
  private Button btn = new Button();

  public Foo(IForm ctx) {
     btn.Name = "MyButton";
     btn.ButtonClick += ctx.Button_OnClick;
     Controls.Add(btn);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...