c#中的静态事件与非静态事件有何不同?

本文关键字:静态 事件 何不同 | 更新日期: 2023-09-27 18:05:41

我刚刚意识到静态事件的存在——我很好奇人们是如何使用它们的。我想知道静态方法与实例方法的相对比较是如何进行的。例如,静态方法基本上是一个全局函数。但是我总是将事件与对象的实例联系起来,并且我很难在全局级别上考虑它们。

这里有一些代码可以参考,如果它有助于解释:
void Main()
{
    var c1 = new C1();
    c1.E1 += () => Console.WriteLine ("E1");
    C1.E2 += () => Console.WriteLine ("E2");
    c1.F1();
}
// <<delegate>>+D()
public delegate void D();
// +<<event>>E1
// +<<class>><<event>>E2
// +F()
//      <<does>>
//          <<fire>>E1
//          <<fire>>E2
public class C1
{
    public void F1()
    {
        OnE1();
        OnE2();
    }
    public event D E1;
    private void OnE1()
    {
        if(E1 != null)
        {
            E1();
        }
    }
    static public event D E2;
    static private void OnE2()
    {
        if(E2 != null)
        {
            E2();
        }
    }
}

c#中的静态事件与非静态事件有何不同?

小心静态事件。请记住,当对象订阅事件时,对该对象的引用由事件的发布者持有。这意味着您在显式地取消订阅静态事件时必须非常小心,因为它们将使订阅者永远保持活动状态,也就是说,您可能会以托管的内存泄漏结束。

OOP的大部分内容可以从消息传递的角度来考虑。

方法调用是从调用方传递给被调用方(携带参数)的消息,并返回带有返回值的消息。

事件是从源发送到订阅者的消息。因此,可能涉及到两个实例,一个发送消息,一个接收消息。

对于静态事件,没有发送实例(只有类型,可以是也可以不是类)。仍然可以将收件人实例编码为委托的目标。

如果您不熟悉静态方法

你可能已经熟悉静态方法了。一个容易理解的区别是,你不需要创建一个对象的实例来使用静态方法,但你需要创建一个对象的实例来调用非静态方法。

一个很好的例子是System.IO.Directory和System.IO.DirectoryInfo类。

Directory类提供静态方法,而DirectoryInfo类没有。

这里有两篇描述它们的文章,你可以自己看看它们的区别。

http://visualcsharptutorials.com/2011/01/system-io-directory-class/

http://visualcsharptutorials.com/2011/01/system-io-directoryinfo-class/

现在静态事件…

然而,静态事件在野外很少见到。在极少数情况下,我认为opf实际上是我想要使用的,但是有一篇CodeProject文章确实展示了一种潜在的用途。

http://www.codeproject.com/KB/cs/staticevent.aspx

这里的关键思想摘自解释(粗体是我加的,以指出相关文本):

我们把这个属性看作是一个单独的对象,我们确保在那里一次只有一个实例。所有的例子事务知道在需要的时候到哪里去找它。有罚款尽管不同。交易就不需要知道了汇率上发生的变化,他们反而会用最后一种在它们通过请求当前值使用它时更改的值价值。这是不够的,例如,当我们想要实现一个的变化,用户界面立即作出反应的应用程序像字体这样的UI特征,就好像它必须发生在实时的。如果我们有一个静态属性,这将是非常容易的在名为currentFont的Font类和一个要更改的静态方法中该值和一个静态事件发送给所有实例,让它们知道何时他们需要更新他们的外观。

作为。net开发人员,我们被训练使用一个断开连接的模型。想想ADO。. NET与经典ADO相比。在VB6应用程序中,你可以使用数据控件,允许以下功能:如果你在你的PC上运行应用程序,当另一台PC上的人编辑数据时,网格中的数据将更新。

这不是。net开发人员所习惯的。我们已经习惯了不连接的模式。静态事件使更"连接"的体验。(即使这种经历是我们不习惯的)

查看此链接http://www.codeproject.com/KB/cs/staticevent.aspx

可以使用静态事件
  • 当没有实例存在时
  • 为所有现有实例做一些多播事件…
  • 当你有一个静态类可以触发事件…

但是人们应该谨慎地使用它们…见讨论http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/2ac862f346b24a15/8420fbd9294ab12a%238420fbd9294ab12a?sa=X&oi=groupsr&start=1&num=2

更多信息

http://msdn.microsoft.com/en-us/library/8627sbea.aspx
http://dylanbeattie.blogspot.com/2008/05/firing-static-events-from-instance.html
http://www.nivisec.com/2008/09/static-events-dont-release.html

静态成员不是"全局的",它们只是的成员,而不是类实例的成员。对于事件、方法、属性、字段等都是如此。

我不能给出一个使用静态事件的例子,因为我通常不认为静态成员在大多数情况下有用。(它们倾向于暗示反模式,比如Singleton)