繁体   English   中英

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

[英]How to add a delegate to an interface C#

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

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

如何?

我的班级看起来像这样:

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
{
   // ?????
}

那些是宣布代表类型 它们不属于界面。 使用这些委托类型的事件可以在接口中使用:

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

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

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

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

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

   public event Action Started;
}

只需将委托作为属性公开

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

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

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

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

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

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

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

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

你的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

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

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

例如,使用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);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM