如何将代理添加到接口C#

时间:2010-10-16 11:33:46

标签: c# interface delegates

我需要在班上有一些代表。

我想使用界面“提醒”我设置这些代表。

如何?

我的班级看起来像这样:

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 个答案:

答案 0 :(得分:126)

这些是声明委托类型。它们不属于界面。事件使用这些委托类型可以在界面中完成:

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

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

实现不会(也不应该)重新声明委托类型,而不是重新声明接口中使用的任何其他类型。

答案 1 :(得分:27)

从.NET 3.5开始,您还可以使用System.Action委托,这将产生以下接口:

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

   public event Action Started;
}

答案 2 :(得分:7)

Jon Skeet的回答是对的,我只想添加一个注释。

接口不用于“提醒”您要做什么,或者在课程中包含什么。接口是抽象的手段,用于面向对象的编程和设计方法。也许你根本不需要接口声明,除非你想看到一些具体的类实例作为你程序中其他地方的接口(抽象)。

如果要在项目中强制执行某些编码标准,可能需要尝试使用代码分析工具(如Visual Studio中) - 它们允许扩展,您可以合并添加自己的代码分析规则。

使用代码分析,如果你“忘记”添加代理(虽然我没有看到忘记它的点,好像没有使用委托,也不需要),你会收到警告/错误。

答案 3 :(得分:7)

将代理公开为属性

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

public interface IMyInterface
{       
    UpdateStatusEventHandler StatusUpdated {get; set;}    
    StartedEventHandler Started {get; set;}
}

答案 4 :(得分:1)

您的一条评论引用了事件处理程序的返回类型。您是否更关心处理程序的类型或从事件中返回的数据?如果是后者,那么这可能会有所帮助。如果没有,那么这个解决方案是不够的,但可能会让你更接近你正在寻找的东西。

您所要做的就是在界面和实现中将事件处理程序声明为通用事件处理程序,您可以自定义返回结果。

你的conrete类看起来像这样:

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;
}

现在事件args正在返回您的类型,您可以将它们挂钩到您定义的任何处理程序中。

供参考: https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx

答案 5 :(得分:0)

在派生类中继承的接口将提醒您定义和链接您在其中声明的内容。

但是你可能也想明确地使用它,你仍然需要将它与一个对象相关联。

例如使用反转控制模式:

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);
  }
}