How to mimic singlecast events in C#

January 12, 2015, (updated on February 13, 2015), Software Development

C# only supports multicast events and delegates. Even if you define a delegate property without the event keyword, it still remains multicasted:

public class Foo
{
    public Action MyEvent { get; set; }
}

var foo = new Foo();
foo.MyEvent += delegate { }; 
foo.MyEvent += delegate { }; 

The only difference between a regular property with a delegate type and an event property are:

  • The event property can only be invoked by its class, the delegate in the regular property can also be invoked from outside (which may not be desired)
  • Accessing and assigning an event property is only allowed within the class
  • The event property provides add and remove accessors instead of set and get accessors

In the end, the event keyword does only change the way a delegate can be accessed and invoked; the underlying type is the same.

However there is a way to mimic a singlecast event property for the clients of a class:

public class Bar
{
    private Action _myAction;
    public event Action MyAction 
    {
        add { _myAction = value; }
        remove { _myAction -= value; }
    }
}

As you can see, adding a new delegate always removes the existing delegate and thus only one delegate can be registered at one time…

Note: The registered delegates are called in the order they are added and a multicast delegate returns the result of the last delegate invocation if it has a return type (e.g. if the delegate is of type Func<T>). Read more on this MSDN article.

Tweet about this on TwitterShare on FacebookEmail this to someoneShare on TumblrShare on LinkedIn

Tags: , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax