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

时间:2011-09-06 09:31:57

标签: 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 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...
}

我的三个问题如下。

Q1。我是否在第一时间在类中声明我自己的代理,即public delegate void DataReceivedHandler,或者是否应删除它们并将事件替换为普通的EventHandler。即public event EventHandler DataReceived。鉴于这些事件没有通过事件传递数据,只是通知已经订阅了某些事情的任何事情。

Q2。与上述问题密切相关。鉴于我正在更改类的属性,即status(StatusUpdated)。将新状态作为自定义EventArgs传递是最佳做法,因此需要原始代码中的自定义委托吗?因为它当前工作,所以事件被触发,并且订阅的类可以只使用发送者值,即(发送者为ClassA).Status。有最好的做法还是仅仅取决于开发人员?

Q3。现在已经过时了。关于界面的部分。我是否正确地在接口中声明了DataReceived和其他事件,以匹配将被标记为实现它的类。

2 个答案:

答案 0 :(得分:1)

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

如果 需要在提升这些事件时传递任何数据,则可以使用普通的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;
}

后一种方法为您提供强类型sender参数(与object中的EventHandler相对)的好处。

答案 1 :(得分:1)

在回答你的问题时,当然这些是意见问题所以我会给我的:

A1)不,你不能重新声明你自己的XXXHandler代表,框架中有一个(EventHandler)与你的完全匹配 - 这是一个很好的迹象表明你是发明轮子“。

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

A3)目前你的班级'事件与界面不匹配,这意味着它无法在没有变化的情况下实现它。

文档:EventHandler<TEventArgs>