HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Raise an event (sample 1)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
sampleraiseevent

Problem

I'm writing tutorials for new programmers. The tutorials show programmers how to structure events.

I've attached the code for one of the tutorials. Can someone take a look at my code and let me know if you see any bugs or gotchas? The goal of the code is to

  • be extremely easy to read and short



  • show a clear separation of the publisher and listener



  • use custom arguments



You can test the code here.

using System;

// program that managers publisher and listener
public class Program
{
    // subscribe to event, raise event
    public static void Main()
    {   
        // new publisher 
        Publisher publisher = new Publisher();
        // new listener
        Listener listener = new Listener();
        // subscribe to event
        listener.Subscribe(publisher);
        // raise event
        publisher.RaiseEvent();         
    }   
}

// object with the event
public class Publisher
{
    // declare event handler
    public delegate void EventHandler(Object sender, RaiseArgs e);
    // declare event
    public static event EventHandler Event;
    // raise event, result: "hello"
    public void RaiseEvent() 
    { 
        RaiseArgs args = new RaiseArgs();
        args.Message = "hello";
        Event(this, args); 
    }
}

// object that listens for the event
public class Listener
{   
    // subscribe to event
    public void Subscribe(Publisher publisher)
    { 
      Publisher.Event += HeardEvent;
    }

    static void HeardEvent(Object sender, RaiseArgs e)
    { Console.WriteLine(e.Message); }       
}

// the arguments to use with an event
public class RaiseArgs : EventArgs
{
    public string Message { get; set; }
}

Solution

I'm bringing your code in line with C#3, which is about 8 years old, so hopefully can be used by your audience. By and large, it's making the class Listener static because it contains no state, using EventHandler to create an event handler rather than using a custom delegate and using var to declare local variables with. I also added some vertical spacing so the code could breathe. The class 'RaiseArgs' is now immutable since the state should remain the same after creation. I like having classes sealed unless my design requires them not to be (it prevents them from being inherited). And lastly, I used a thread-safe access to the event by copying it to a local variable and comparing to null. And now the code:

using System;

// program that managers publisher and listener
public static class Program
{
    // subscribe to event, raise event
    public static void Main()
    {
        // new publisher
        var publisher = new Publisher();

        // subscribe to event
        Listener.Subscribe(publisher);

        // raise event
        publisher.RaiseEvent();
    }
}

// object with the event
public sealed class Publisher
{
    // declare event
    public event EventHandler Event;

    // raise event, result: "hello"
    public void RaiseEvent()
    {
        var handler = Event;

        if (handler != null)
        {
            var args = new RaiseArgs("hello");

            handler(this, args);
        }
    }
}

// object that listens for the event
public static class Listener
{
    // subscribe to event
    public static void Subscribe(Publisher publisher)
    {
        publisher.Event += HeardEvent;
    }

    private static void HeardEvent(object sender, RaiseArgs e)
    {
        Console.WriteLine(e.Message);
    }
}

// the arguments to use with an event
public sealed class RaiseArgs : EventArgs
{
    private readonly string _Message;

    public RaiseArgs(string message)
    {
        _Message = message;
    }

    public string Message
    {
        get
        {
            return _Message;
        }
    }
}

Code Snippets

using System;

// program that managers publisher and listener
public static class Program
{
    // subscribe to event, raise event
    public static void Main()
    {
        // new publisher
        var publisher = new Publisher();

        // subscribe to event
        Listener.Subscribe(publisher);

        // raise event
        publisher.RaiseEvent();
    }
}

// object with the event
public sealed class Publisher
{
    // declare event
    public event EventHandler<RaiseArgs> Event;

    // raise event, result: "hello"
    public void RaiseEvent()
    {
        var handler = Event;

        if (handler != null)
        {
            var args = new RaiseArgs("hello");

            handler(this, args);
        }
    }
}

// object that listens for the event
public static class Listener
{
    // subscribe to event
    public static void Subscribe(Publisher publisher)
    {
        publisher.Event += HeardEvent;
    }

    private static void HeardEvent(object sender, RaiseArgs e)
    {
        Console.WriteLine(e.Message);
    }
}

// the arguments to use with an event
public sealed class RaiseArgs : EventArgs
{
    private readonly string _Message;

    public RaiseArgs(string message)
    {
        _Message = message;
    }

    public string Message
    {
        get
        {
            return _Message;
        }
    }
}

Context

StackExchange Code Review Q#119415, answer score: 3

Revisions (0)

No revisions yet.