C# 关于事件的两个问题

C# 关于事件的两个问题,c#,.net,events,C#,.net,Events,我想知道: Subscriber是订阅事件的类的名称,还是处理事件的方法的名称?我的意思是,说“订阅事件的方法”有意义吗 在MSDN上,它说事件委托应该正好有2个参数。不确定这意味着什么,因为我经常使用自定义委托创建事件,例如,没有或只有一个参数 订阅服务器是作为事件处理程序添加的方法 标准做法是对事件使用EventHandler委托;这有两个论点。 但是,您可以使用任意数量的参数创建自己的事件。订阅服务器是作为事件处理程序添加的方法 标准做法是对事件使用EventHandler委托;这有两个论


我想知道:

  • Subscriber是订阅事件的类的名称,还是处理事件的方法的名称?我的意思是,说“订阅事件的方法”有意义吗

  • 在MSDN上,它说事件委托应该正好有2个参数。不确定这意味着什么,因为我经常使用自定义委托创建事件,例如,没有或只有一个参数


  • 订阅服务器是作为事件处理程序添加的方法

    标准做法是对事件使用
    EventHandler
    委托;这有两个论点。

    但是,您可以使用任意数量的参数创建自己的事件。

    订阅服务器是作为事件处理程序添加的方法

    标准做法是对事件使用
    EventHandler
    委托;这有两个论点。
    但是,您可以使用任意数量的参数创建自己的事件。

    1)是的,谈论向事件订阅方法肯定是有意义的。实际上,您可以认为涉及三个实体:

    • 实际执行订阅本身的订阅代码
    • 事件发布者
    • 正在订阅的处理程序;这通常(但并非总是)与订阅代码位于同一类中
    2) 当然,您可以使用具有任意数量参数的委托创建事件。约定是事件中使用的委托有两个参数:一个“发送者”和一个从
    EventArgs
    派生的“参数”。例如,这意味着您可以将签名为void Foo(object sender,EventArgs e)的方法中的处理程序订阅给遵循约定的任何事件。

    1)是的,将方法订阅给事件绝对有意义。实际上,您可以认为涉及三个实体:

    • 实际执行订阅本身的订阅代码
    • 事件发布者
    • 正在订阅的处理程序;这通常(但并非总是)与订阅代码位于同一类中

    2) 当然,您可以使用具有任意数量参数的委托创建事件。约定是事件中使用的委托有两个参数:一个“发送者”和一个从
    EventArgs
    派生的“参数”。例如,这意味着您可以将签名为void Foo(object sender,EventArgs e)的方法中的处理程序订阅给遵循约定的任何事件。

    我将集中讨论第二点。正如Jon指出的,您可以使用自己的代理进行活动。但你很少应该这样做。即使您不关心约定,也可以这样看:每当您将自己的事件与自定义委托一起使用时,除了事件字段本身之外,您还有以下代码:

    • 您的自定义委托
    • 事件处理程序(具有匹配签名的方法)-有时很多
    • 事件调用点(需要传递所有参数的地方)-有时很多
    • 我还倾向于创建
      InvokeMyEvent
      方法来执行空性检查和其他需要完成的工作
    如果决定添加或删除参数或更改参数类型,则必须更改所有这些

    现在,如果您创建自己的类继承
    EventArgs
    ,或者使用
    EventArgs
    ,那么您有:

    • 您的
      CustomEventArgs
    • 事件处理程序
    • 事件调用点
    • InvokeMyEvent
      方法
    每当您决定更改事件参数时,只需更改自定义参数类和一些事件调用点。“Some”,因为您可以为args类的字段提供合适的默认值,并且仅在需要时提供这些值

    大多数好的/坏的实践演讲都集中在一件事上——易更改性。变化总是发生的。当他们做的时候,你需要改变的事情越少越好。设计需要大量的迭代,很可能您必须大量更改接口和类型。当您决定不再需要该参数时,您不希望更改数十个签名。因此,使用
    EventArgs
    EventArgs
    可以省去一些麻烦

    另一个次要问题是,您可能需要声明一些负责引发事件的方法,如下所示:

    public static public void FireEvent<T>(this EventHandler handler, object sender, EventArgs<T> e)
        where T : EventArgs
    {
        if (handler != null)
            handler(sender, e);
    }
    
    public static public void firevent(此EventHandler处理程序、对象发送方、EventArgs e)
    其中T:EventArgs
    {
    if(处理程序!=null)
    处理人(发送者,e);
    }
    

    如果您的所有事件都是基于
    EventHandler
    ,那么您可以使用一种通用方法来处理类似的事情。如果没有,那么你最终会有几十个。我将集中讨论第二点。正如Jon指出的,您可以使用自己的代理进行活动。但你很少应该这样做。即使您不关心约定,也可以这样看:每当您将自己的事件与自定义委托一起使用时,除了事件字段本身之外,您还有以下代码:

    • 您的自定义委托
    • 事件处理程序(具有匹配签名的方法)-有时很多
    • 事件调用点(需要传递所有参数的地方)-有时很多
    • 我还倾向于创建
      InvokeMyEvent
      方法来执行空性检查和其他需要完成的工作
    如果决定添加或删除参数或更改参数类型,则必须更改所有这些

    现在,如果您创建自己的类继承
    EventArgs
    ,或者使用
    EventArgs
    ,那么您有:

    • 您的
      CustomEventArgs
    • 事件处理程序
    • 事件