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

时间:2010-02-17 17:49:21

标签: c# .net 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”参数值来标识事件调用的发起者。

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

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

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

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

谢谢

5 个答案:

答案 0 :(得分: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; }
}

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

static void SomethingHappenedHandler(object sender, FileEventArgs e)
{
    // do something intelligent
}

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

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; }
}

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

  

我是在假设如果事件的时候写的   然后在静态方法中引发   “对象源”参数是否定的   使用?!

是的,这是正确的。我通常会将null作为static事件的发件人参数传递(实际上,这是非常罕见的)。

答案 1 :(得分:8)

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

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

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

答案 2 :(得分:4)

标准方法的主要好处之一就是它在锡上做了它所说的事实。 标准方法意味着任何查看代码的开发人员都会立即了解正在发生的事情,以及如何使用您的事件。

答案 3 :(得分:3)

个人而言,我不会一直遵循本指南,仅针对将要发布以进行一般性重用的工作

为什么呢?

  • 因为我并不总是需要知道事件的发件人
  • 因为将委托参数 - 特别是当只有一个 - 移动到一个单独的类时是过度的

是的,我知道,这些争论可能会在未来发生变化。但是YAGNI。坦率地说,当我必须更改事件委托中的参数时,编译器会方便地告诉我每个使用它的地方,以便我可以检查它们是否正确处理了新参数。如果我遵循标准并使用自定义EventArgs类,我将不得不手动搜索这些地方。

所以,像往常一样,“它取决于”“使用你自己的判断”申请: - )

答案 4 :(得分:2)

如果您使用标准事件签名并且您的事件参数继承自eventargs,则可以使用通用事件处理程序委托(EventHandler&lt; TEventArgs&gt;)。

public event EventHandler<MyCustomEventArgs> MyEvent;

http://msdn.microsoft.com/en-us/library/db0etb8x.aspx