C# Bubbling/Passing Along An Event

送分小仙女□ 提交于 2019-12-03 17:07:06

If I understood what you wanted in the basic sense. Is to have the Tweeter and Woofer fire an event that the Speaker is subscribed too then fire its own.

Here is my code that has this output

OUTPUT

OnSpeak Message = OnSpeakToMeHander Orginal Message: Fired By Tweeter

OnSpeak Message = OnSpeakToMeHander Orginal Message: Fired By Woofer

class Program
{

    static void Main(string[] args)
    {
        Console.Clear();

        try
        {
            Speaker speaker = new Speaker();
            speaker.speakerEvent += new SpeakToMeHandler(Program.OnSpeak);

            // Cause events to be fied
            speaker.Tweeter.CauseEvent();
            speaker.Woofer.CauseEvent();

        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: {0}", ex.Message);
            Console.WriteLine("Stacktrace: {0}", ex.StackTrace);
        }
    }

    public static void OnSpeak(object sendere, SpeakToMeEventArgs e)
    {
        Console.WriteLine("OnSpeak Message = {0}", e.Message);
    }

}

public delegate void SpeakToMeHandler(object sender, SpeakToMeEventArgs e);

public class SpeakToMeEventArgs : EventArgs
{
    public string Message { get; set; }
}

public class Speaker
{
    public event SpeakToMeHandler speakerEvent;

    public Tweeter Tweeter { get; set; }
    public Woofer Woofer { get; set; }

    public void OnSpeakToMeHander(object sender, SpeakToMeEventArgs e)
    {
        if (this.speakerEvent != null)
        {
            SpeakToMeEventArgs args = new SpeakToMeEventArgs
                {
                    Message = string.Format("OnSpeakToMeHander Orginal Message: {0}", e.Message)
                };

            this.speakerEvent(this, args);
        }
    }

    public Speaker()
    {
        this.Tweeter = new Tweeter();
        this.Woofer = new Woofer();

        Tweeter.tweeterEvent += new SpeakToMeHandler(this.OnSpeakToMeHander);
        Woofer.wooferEvent += new SpeakToMeHandler(this.OnSpeakToMeHander);
    }
}

public class Tweeter
{
    public event SpeakToMeHandler tweeterEvent;

    public void CauseEvent()
    {
        SpeakToMeEventArgs args = new SpeakToMeEventArgs()
            {
                Message = "Fired By Tweeter"
            };

        if (this.tweeterEvent != null)
        {
            this.tweeterEvent(this, args);
        }
    }
}

public class Woofer
{
    public event SpeakToMeHandler wooferEvent;

    public void CauseEvent()
    {
        SpeakToMeEventArgs args = new SpeakToMeEventArgs()
            {
                Message = "Fired By Woofer"
            };

        if (this.wooferEvent != null)
        {
            this.wooferEvent(this, args);
        }
    }
}

Eric Lippert warns against if (SpeakToMe != null) code. While it might not be an issue in your case (i.e. if you never remove events), you should get into the habit of using this instead:

var tmp = SpeakToMe;
if (tmp!=null) tmp(/*arguments*/);

In C#6 and higher, consider this terser code instead:

SpeakToMe?.Invoke(e)

The latter approach is suggested on the MSDN

The only way the delegate will be null is if the form is actually NOT subscribed to the event. Did you create a new instance of speaker at some point? If you had subscribed one instance, and then created a new instance using the same variable, the events for the new instance will not be hooked up.

You can use the long form of event declaration to pass the event to an internal object.

public class Speaker
{
    public Speaker()
    {
        this.MyTweeter = new Tweeter();
    }

    public Tweeter MyTweeter { get; private set; }

    public event SpeakToMeHandler SpeakToMe
    {
        add { MyTweeter.SpeakToMe += value; }
        remove { MyTweeter.SpeakToMe -= value; }
    }
}

Rather than passing the event, why not assign an additional handler for the event? You aren't limited to just one method.

//Handler class
public class Speaker {
    public delegate void HandleMessage(string message);
    public event HandleMessage OnMessage;
    public void SendMessage(string message) {
        if (OnMessage != null) { OnMessage(message); }
    }
}

//then used like...
Speaker handler = new Speaker();
handler.OnMessage += (message) => { Console.WriteLine("Woofer: {0}", message); };
handler.OnMessage += (message) => { Console.WriteLine("Tweeter: {0}", message); };
handler.SendMessage("Test Message");
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!