Home Artikelen Events vs. delegates

15

Jul

2006

Events vs. delegates

Het verschil tussen een Delegate en een Event

Er zijn enorm veel overeenkomsten tussen een delegate en een event. De verklaring is dan ook simpel, volgens de documentatie van C# is het event keyword gewoon een modifier voor een delegate. Toch zijn er een aantal dingen die je met delegates wel kunt en met events niet en versavisa.

Om te beginnen verschild de += en -= operator al. In tegenstelling tot een delegate is deze bij een event wel thread-safe.
Events zijn altijd multi-cast terwijl Delegates in .NET 1.0 Beta nog single-cast waren, wat inhoud dat er maar 1 method invoked kan worden. Maar sinds de RTM versie van .NET 1.0 zijn Delegates ook multi-cast en zit hier dus geen verschil meer in.

Meerwaarde van Events

Volgens de documentatie van C# is het event keyword gewoon een modifier voor een delegate. Dit verklaard gelijk waarom er zoveer overeenkomsten zijn tussen delegates en events. Toch zijn er een aantal dingen die je met delegates wel kun en met events niet en versavisa natuurlijk.

Als een class een public delegate bevat kun je deze altijd invoken. Hier een klein voorbeeld wat zonder problemen compiled:

namespace Born2Code.Net
{
    public delegate void MessageHandler( String message );
 
    public class Melp
    {
        public MessageHandler MessageReceived;
        public Melp()
        {
            // Nothing todo.
        }
    }
 
    public static class Program
    {
        public static void Main( String[] arguments )
        {
            Melp m = new Melp();
            m.MessageReceived( "My message" );
        }
    }
}

Iets wat met een event niet kan, je krijgt namelijk een CS0070 om je oren. Hier een klein voorbeeld wat niet zonder problemen compiled:

namespace Born2Code.Net
{
    public delegate void MessageHandler( String message );
 
    public class Melp
    {
        public event MessageHandler MessageReceived;
 
        public Melp()
        {
            // Nothing todo.
        }
    }
 
    public static class Program
    {
        public static void Main( String[] arguments )
        {
            Melp m = new Melp();
            m.MessageReceived( "My message" ); // Error CS0070
        }
    }
}

Zoals je ziet kunnen events niet buiten de class geinvoked worden. Ook de invocation list en de target kan van een event niet worden opgevraagt buiten zijn eigen class. Het enige wat je met een event buiten zijn eigen class kunt is subscriben en unsubscriben. De subscribe en unsiscribe kunnen ook nog is met een accessor geregeld worden. Hier een voorbeeld:

Dit brengt ons gelijk bij nog een leuk verschil, delegates en interfaces. Een interface mag wel een event bevatten maar geen delegate! Hier een voorbeeld dat niet zonder problemen compiled:

namespace Born2Code.Net
{
    public delegate void MessageHandler( String message );
    public interface IMelper
    {
        event MessageHandler MessageReceived;
        event MessageHandler MessageSend;
    }
 
    public class Melp : IMelper
    {
        public MessageHandler MessageReceived; // Normal implementation.
        private MessageHandler _messageSend;
 
        event MessageHandler IMelper.MessageSend // Explicit implementation.
        {
            add
            {
                _messageSend += value;
                Console.WriteLine( "{0} added.", value.Method.Name );
            }
            remove
            {
                _messageSend -= value;
                Console.WriteLine( "{0} removed.", value.Method.Name );
            }
        }
 
        public Melp()
        {
            // Nothing todo.
        }
    }
}

Meerwaarde van delegates

In tegenstelling tot events kennen delegates assignments, dit kan op meerderen manieren. Hier wat sample code rechtstreeks van de MSDN Documentatie:

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod; //Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2; allMethodsDelegate += d3;

In het kort

Nu we de verschillen hebben bekeken nog even de punten op een rij:

  • += en -= operator zijn in tegenstelling tot een delegate bij een event wel thread-safe
  • Events zijn altijd multi-cast, delegates sinds de RTM versie van .NET 1.0 ook.
  • Het Event keyword is een modifier voor een delegate.
  • Een delegate member kan ook buiten zijn owner class worden geinvoked, iets wat bij een even niet mogelijk is.
  • Een event kan een accessor hebben.
  • Een interface kan een event member hebben, maar geen delegate member.
  • Assignments zijn wel mogelijk op delegates.
Trackback(0)
Commentaar (0)Add Comment

Schrijf commentaar
quote
bold
italicize
underline
strike
url
image
quote
quote
smile
wink
laugh
grin
angry
sad
shocked
cool
tongue
kiss
cry
smaller | bigger

busy
 

Quote XNA presentatie

Bedankt voor je schitterende presentatie. Ik heb niets dan positieve geluiden gehoord.

Peter Criellaard
Microsoft

Quote Coding dilemma's

Eindelijk een presentatie waarmee ik ook iets mee kan in de praktijk!

Dennis Schuuring
Max BV

Quote C# fun!

Bedankt voor de presentatie, het was voor mij 1 van de betere momenten van die dag!

Henri Koppen
Arcenus