简体   繁体   English

static 事件与 C# 中的非静态事件相比如何?

[英]How do static events compare to non-static events in C#?

I just realized static events exist - and I'm curious how people use them.我刚刚意识到 static 事件存在 - 我很好奇人们如何使用它们。 I wonder how the relative comparison holds up to static vs. instance methods.我想知道相对比较如何支持 static 与实例方法。 For instance, a static method is basically a global function.例如,static 方法基本上是全局 function。 But I've always associated events with instances of objects and I'm having trouble thinking of them at the global level.但是我总是将事件与对象的实例相关联,并且在全局层面上思考它们时遇到了麻烦。

Here some code to refer to if it helps an explanation:这里有一些代码可以参考,如果它有助于解释:

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

Be wary of static events.警惕 static 事件。 Remember that, when an object subscribes to an event, a reference to that object is held by the publisher of the event.请记住,当 object 订阅事件时,对该 object 的引用由事件的发布者持有。 That means that you have to be very careful about explicitly unsubscribing from static events as they will keep the subscriber alive forever, ie, you may end up with the managed equivalent of a memory leak.这意味着您必须非常小心地明确取消订阅 static 事件,因为它们将使订阅者永远活着,也就是说,您最终可能会遇到 memory 泄漏的托管等效项。

Much of OOP can be thought of in terms of message passing. OOP 的大部分内容都可以从消息传递的角度来考虑。

A method call is a message from the caller to the callee (carrying the parameters) and a message back with the return value.方法调用是从调用者到被调用者的消息(携带参数)和返回值的消息。

An event is a message from the source to the subscriber.事件是从源到订阅者的消息。 There are thus potentially two instances involved, the one sending the message and the one receiving it.因此可能涉及两个实例,一个发送消息,一个接收消息。

With a static event, there is no sending instance (just a type, which may or may not be a class).对于 static 事件,没有发送实例(只是一个类型,可能是也可能不是类)。 There still can be a recipient instance encoded as the target of the delegate.仍然可以有一个接收者实例被编码为委托的目标。

In case you're not familiar with static methods如果您不熟悉 static方法

You're probably already familiar with static methods.您可能已经熟悉 static 方法。 In case you're not, An easy-to-understand difference is that you don't need to create an instance of an object toi use a static method, but you DO need to create an instance of an object to call a non-static method.如果你不是,一个易于理解的区别是你不需要创建一个 object 的实例来使用 static 方法,但你需要创建一个 ZA8CFDE6331BD49EB2AC96F8911 的实例静态方法。

A good example is the System.IO.Directory and System.IO.DirectoryInfo classes.一个很好的例子是 System.IO.Directory 和 System.IO.DirectoryInfo 类。

The Directory class offers static methods, while the DirectoryInfo class does not.目录 class 提供 static 方法,而 DirectoryInfo class 不提供。

There are two articles describing them here for you to see the difference for yourself.这里有两篇文章对它们进行了描述,您可以自己看看它们的区别。

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

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

Now on to static events ...现在到 static事件...

However, static events are seldom seen in the wild.然而,static 事件在野外很少见。 There are very few cases that I can think opf where I'd actually want to use one, but there is a CodeProject article that does show one potential use.在极少数情况下,我认为 opf 我实际上想要使用一个,但有一篇 CodeProject 文章确实显示了一种潜在用途。

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

The key thought here is taken from the explanation (bold added by me to point out the relevant text):这里的关键思想来自解释(我添加的粗体以指出相关文本):

We saw this property as a separate object and we made sure that there is only one instance of it at a time.我们将此属性视为单独的 object,并确保一次只有一个实例。 And all instances of transactions knew where to find it when needed.并且所有事务实例都知道在需要时在哪里找到它。 There is a fine difference though.不过有一个很好的区别。 The transactions will not need to know about the changes happening on the exchange rate, rather they will use the last changed value at the time that they use it by requesting the current value.交易不需要知道汇率发生的变化,而是通过请求当前值来使用上次更改的值。 This is not enough when, for example, we want to implement an application where the user interface reacts immediately on changes in the UI characteristics like font, as if it has to happen at real-time.这还不够,例如,当我们想要实现一个应用程序时,用户界面会立即对字体等 UI 特征的变化做出反应,就好像它必须实时发生一样。 It would be very easy if we could have a static property in the Font class called currentFont and a static method to change that value and a static event to all instances to let them know when they need to update their appearance. It would be very easy if we could have a static property in the Font class called currentFont and a static method to change that value and a static event to all instances to let them know when they need to update their appearance.

As .NET developers we're trained to work with a disconnected model.作为 .NET 开发人员,我们经过培训可以使用断开连接的 model。 Think of ADO.NET compared to classic ADO.将 ADO.NET 与经典 ADO 相比较。 IN a VB6 app, you could use data controls that would allow the following functionality: If you were running the app on your PC, the data in your grid would update when someone on another PC edited the data.在 VB6 应用程序中,您可以使用允许以下功能的数据控件:如果您在 PC 上运行该应用程序,则当另一台 PC 上的某人编辑数据时,网格中的数据将更新。

This isn't something that .NET developers are used to.这不是 .NET 开发人员习惯的东西。 We're very used to the disconnected model.我们非常习惯断开连接的 model。 Static events enable a more "connected" experience . Static 事件可实现更“连接”的体验 (even if that experience is something we're not used to any more.) (即使这种体验我们已经不习惯了。)

Static members are not "global," they are simply members of the class , not of class instances . Static 成员不是“全局的”,它们只是class的成员,而不是class 实例的成员。 This is as true for events as it is for methods, properties, fields, etc.这对于事件和方法、属性、字段等都是如此。

I can't give an example for using a static event, because I generally don't find static members to be useful in most cases.我无法举出使用 static 事件的示例,因为我通常不认为 static 成员在大多数情况下有用。 (They tend to hint at anti-patterns, like Singleton.) (他们倾向于暗示反模式,例如 Singleton。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM