为什么在《 C#编程指南》的EventHandler示例中有任意代码?

时间:2019-07-01 10:10:22

标签: c# events delegates event-handling

我试图更好地理解C#编程指南文档中的示例。我已经看过它在Visual Studio中逐步执行,并阅读了文档以获取线索。

它使用通用的EventHandler委托。这是代码:

using System;
using System.Collections.Generic;

namespace DotNetEvents
{
    class Program
    {

    class CustomEventArgs : EventArgs
        {
            public CustomEventArgs(string s)
            {
                message = s;
            }
            private string message;

            public string Message
            {
                get { return message; }
                set { message = value; }
            }

        }

        class Publisher
        {
            public event EventHandler<CustomEventArgs> RaiseCustomEvent;

            public void DoSomething()
            {
                Console.WriteLine("Did something");
            }

            protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
            {
                EventHandler<CustomEventArgs> handler = RaiseCustomEvent;

                if(handler != null)
                {
                    e.Message += $" at {DateTime.Now}";

                    handler(this, e);
                }
            }
        }

        class Subscriber
        {
            private string id;
            public Subscriber(string ID, Publisher pub)
            {
                id = ID;
                pub.RaiseCustomEvent += HandleCustomEvent;
            }

           void HandleCustomEvent(object sender, CustomEventArgs e)
            {
                Console.WriteLine(id + " received this message: {0}", e.Message);
            }
        }
        static void Main(string[] args)
        {
            Publisher pub = new Publisher();
            Subscriber sub1 = new Subscriber("sub1", pub);
            Subscriber sub2 = new Subscriber("sub2", pub);

            pub.DoSomething();

            Console.ReadKey();
        }
    }
}

为什么以下行看起来完全是任意的:

protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
            {
                EventHandler<CustomEventArgs> handler = RaiseCustomEvent;

                if(handler != null)
                {
                    e.Message += $" at {DateTime.Now}";

                    handler(this, e);
                }
            }

如果注释掉,此方法中的任何内容都不会影响结果。此外,我注释了以下几行,但似乎没有任何影响:

//pub.RaiseCustomEvent += HandleCustomEvent;

/* void HandleCustomEvent(object sender, CustomEventArgs e)
            {
                Console.WriteLine(id + " received this message: {0}", e.Message);
            } */

了解为什么要添加这些东西会很有帮助。谢谢。作为参考,这是我从中获取代码的页面。我删除了它的一些注释,因为我是在键入它而不是复制和粘贴。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-publish-events-that-conform-to-net-framework-guidelines

1 个答案:

答案 0 :(得分:1)

当您调用pub.RaiseCustomEvent += HandleCustomEvent时,此代码本身除了将方法注册到事件外,不会执行任何操作。当您从未引发该事件时,该方法(我们称为事件处理程序)肯定不会执行。

在您的代码中,您将通过在您的OnRaiseCustomEvent类中的某个地方调用Publisher引发该事件。但是,我们不知道该事件何时真正触发。

例如,只要某个客户端在任何DoSomething实例上调用Publisher,您就可以引发该事件。然后,您可以从OnRaiseCustomEvent方法中调用DoSomething

public void DoSomething()
{
    OnRaiseCustomEvent(new CustomEventArgs("I did something"));
    Console.WriteLine("Did something");
}

这是当您调用pub.DoSomething时引发的事件,并且将调用事件处理程序(HandleCustomEvent)。