C# 事件处理程序,现有类到新接口

C# 事件处理程序,现有类到新接口,c#,.net,events,interface,delegates,C#,.net,Events,Interface,Delegates,我正在为一个项目增加一些灵活性,因为它的目的现在已经改变了。我想添加一个现有类将实现的接口 现有类 public class ClassA { #region Events public delegate void DataReceivedHandler(object sender, EventArgs e); public delegate void DataSentHandler(object sender, EventArgs e); public dele

我正在为一个项目增加一些灵活性,因为它的目的现在已经改变了。我想添加一个现有类将实现的接口

现有类

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...
}
我的三个问题如下

问题1。首先,我在类中声明自己的委托是正确的,例如,
公共委托void DataReceivedHandler
,还是应该删除这些委托并用普通事件处理程序替换事件。i、 e.
已接收公共事件事件处理程序数据
。假设这些事件不随事件一起传递数据,只需通知订阅的任何内容,说明某些内容已更改

问题2。与上述问题密切相关。假设我正在更改类的属性,即status(StatusUpdated)。最佳做法是将新状态作为自定义EventArgs传递,从而像原始代码那样需要自定义委托吗?当它当前工作时,事件被触发,并且订阅的类可以只使用发送者值,即(发送者为ClassA).Status。是否有最佳实践,还是由开发人员决定


第三季度。现在,这是不可能的。关于接口的部分。我是否已在接口中正确声明DataReceived和其他事件,以匹配将被标记为实现它的类。

如果需要接口方法的自定义委托,则应单独声明它们(在类之外),因为它们与特定实现无关。委托声明可以位于接口内部,就像类一样。您的代表的问题是,他们都具有相同的签名(即
事件处理程序的签名),因此是多余的

如果在引发这些事件时,不需要传递任何数据,则可以使用普通EventHandler委托。但是,我希望通过
DataReceived
事件获得一些数据,因此您应该检查这是否合理,并可能使用接受某些数据作为参数的委托

第三,接口事件签名必须与类签名匹配。不能在接口中使用
EventHandler
委托类型,也不能在类内更改签名

请注意,您还可以避免显式声明委托类型,并使用BCL提供的泛型
Action
委托(从.NET 3.5开始)。在这种情况下,您可能会遇到以下情况:

public interface IClassA
{
   event Action<IClassA, Data> DataReceived;
   event Action<IClassA, Data> DataSent;
   event Action<IClassA, Status> StatusUpdated;
}
公共接口IClassA
{
收到事件行动数据;
事件动作数据集;
事件动作状态更新;
}

后一种方法的好处是,在
EventHandler
中有一个强类型的
发送方
参数(与
对象
相对)。

在回答您的问题时,这些当然是一个意见问题,因此我将给出我的:

A1)不,您不能重新声明自己的
XXXHandler
委托,框架中有一个(
EventHandler
)与您的完全匹配-这很好地表明您正在“发明轮子”

A2)我认为一个名为
StatusChanged
的事件应该将新的(可能是旧的)状态传递给任何订阅者。但是,这仍然不是实现您自己的委托的理由,因为框架定义了一个通用委托(
EventHandler
),正是为了实现此目的

A3)目前,您的类的事件与接口不匹配,这意味着如果不进行更改,它将无法实现它


博士:

比Groo更简洁的回答,但我喜欢行动的使用。除了对他的回答的评论中的一个缺点,我已经尝试了两种方法,你的和Jamiecs,谢谢你们的回答。我更喜欢使用Action,因为我见过它也用于GUI调用,所以我习惯了这是个好主意。我看到这种方法唯一的缺点是缺少自动完成功能。如果我输入myClassA.StatusUpdated+=…,则使用我以前的事件。。。。+=将自动创建处理事件的方法,即使使用自定义事件参数也是如此。使用操作时,情况并非如此,您必须自己编写方法。选择强类型发送者是另一个原因,尽管这似乎可以通过委托实现。@Jon:确定吗?我从来没有遇到过这样的问题,不管委托签名是什么(键入
+=
,按两次
选项卡
,应该会生成方法存根)。只需在重新打开VS2008后重试,就可以了。奇怪的