使活动符合Net准则有什么好处?

Asp*_*Net 7 .net c# events

我了解如何根据Net Framework指南使用事件,但使用此模式有什么好处?

http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx:

.NET Framework准则指出用于事件的委托类型应该采用两个参数,一个"对象源"参数指示事件的来源,一个"e"参数封装有关该事件的任何其他信息."e"参数的类型应该来自EventArgs类.对于不使用任何其他信息的事件,.NET Framework已经定义了适当的委托类型:EventHandler.

a)我看到使用"对象源"值作为第一个参数的一些好处,因为有些情况下多个对象可以将它们的事件设置为相同的方法.因此,例如,如果我们有10个对象,并且如果所有10个对象将它们的事件设置为事件处理程序M,那么在M内部我们可以使用"object sender"参数值来标识事件调用的发起者.

  • 但据我所知,"对象源"参数仅在事件方法中引发事件时才有用.因此,如果在静态方法中引发了事件,那么"对象源"参数是没有用的?!

b)根据Net Framework准则使用事件是否还有其他好处?

c)无论可能带来什么好处,为什么他们会超越必须的麻烦

  • 编写一个额外的代码,将所需的参数放入从EventArgs派生的对象中
  • 在事件处理程序中编写一个额外的代码,以从EventArgs派生的对象中提取信息?

谢谢

Fre*_*örk 10

据我所知,有两个主要好处:

  • 编写消耗该事件的代码的人将识别该模式并立即知道如何使用该事件
  • 该活动的签名以一种强大的变革方式精心设计

第一点应该是非常明显的,不需要太多详细说明.

至于第二点,有两个原因(在我看来).首先,由于发送者是object,所以事件签名可以由几种类型重用.其次,由于第二个参数是一个EventArgs后代,当你引入自己的EventArgs类时,这个类可以在以后扩展而不改变事件的签名.

更新
对问题的回复:

我不确定你的意思是"能够在不改变事件签名的情况下扩展EventArgs"?!

我们举一个例子,参加以下课程:

public class SomeClass
{
    public event EventHandler<FileEventArgs> SomethingHappened;
}
public class FileEventArgs : EventArgs
{
    public FileEventArgs(string filename)
    {
        Filename = filename;
    }
    public string Filename { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我们有一个听取SomethingHappened事件的消费者:

static void SomethingHappenedHandler(object sender, FileEventArgs e)
{
    // do something intelligent
}
Run Code Online (Sandbox Code Playgroud)

现在,假设我们想要扩展我们在事件中传输的信息,并提供有关文件发生的信息:

public enum WhatHappened
{
    Copy,
    Rename,
    Delete
}
public class FileEventArgs : EventArgs
{
    public FileEventArgs(string filename, WhatHappened whatHappened)
    {
        Filename = filename;
        WhatHappened = whatHappened;
    }
    public string Filename { get; private set; }
    public WhatHappened WhatHappened { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们选择在事件本身中将文件名作为参数发送,我们需要通过添加另一个参数来更改事件签名,从而有效地破坏所有侦听事件的代码.但由于我们在上面的代码中只是简单地向FileEventArgs类中添加了另一个属性,因此签名保持不变,并且不需要更新任何侦听器(除非他们想要使用新添加的属性,即).

我是在假设如果在静态方法中引发事件,那么"对象源"参数是没用的吗?!

对,那是正确的.我通常null作为发件人参数传递static事件(老实说,这是非常罕见的).

  • @AspOnMyNet:从技术上讲,你永远不应该得到一个发件人与你订阅该事件的对象不同的事件.由于静态事件没有对象(没有此引用),因此sender为null.当然,实现可以自由地将任何内容放入发送方,但它不应该. (3认同)

Ore*_*ost 8

如果您遵守.NET Framework准则,不仅是针对事件,而且针对所有事情,需要阅读您的代码或使用您的库的人会识别它,使他的事情变得更简单.这总是一件好事,因为您应该为您的读者编写代码,而不是为了您的方便..NET的好处在于,从一开始就有一些标准指南,与数以千计的C++约定相比,大多数人都知道它并应用它.

标准事件处理程序签名的附加好处是,您可以将不太专业的事件处理程序(例如,等EventHandler)分配给更专业类型的事件,如果有人不需要其他数据,则可以简化开发.它还使通过Reflection添加事件处理程序变得更加简单,这在某些情况下可能很有用(比如某个对象模型的对象层次结构浏览器) - 我可以向您保证,通过Reflection 处理任何事件的代码是一个复杂的事情,我解决了通过为每个事件发出IL代码,我一直认为这是最后的手段.

正如FredrikMörk在同一时间写的那样,这使得稍后通过向EventArgs派生类添加参数而不是向每个事件处理程序添加参数也更容易扩展事件.