Why events if we have delegates

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • puzzlecracker

    Why events if we have delegates

    I took a closer look at delegates and events, and it became apparent
    that events don't offer any extra functionalities over delegates. I
    don't even see it as syntactical sugar over "overtly obfuscated"
    delegate syntax. Moreover, you can accomplish everything with
    delegates that you can accomplish with events, such as combining
    instances, etc.

    Am I missing something here?

    Thanks
  • Peter Duniho

    #2
    Re: Why events if we have delegates

    On Tue, 28 Oct 2008 09:57:08 -0700, puzzlecracker <ironsel2000@gm ail.com>
    wrote:
    I took a closer look at delegates and events, and it became apparent
    that events don't offer any extra functionalities over delegates. I
    don't even see it as syntactical sugar over "overtly obfuscated"
    delegate syntax. Moreover, you can accomplish everything with
    delegates that you can accomplish with events, such as combining
    instances, etc.
    >
    Am I missing something here?
    Yes. You are missing the fact that if you use a delegate, you are forced
    to use the delegate's mechanism for adding and removing method groups. If
    you write an event, you have the ability to manage the subscription
    however you like. For example, the Control class maintains a dictionary
    for each event. There's a little overhead for the dictionary, but there's
    _zero_ storage for each event unless it's actually subscribed. For a
    class like Control (and its subclasses) that have a huge number of events
    that are almost never subscribed to, this is a very significant memory
    savings.

    The other thing you're missing is that an event _encapsulates_ the
    delegate. That is, while the semantics are similar, only the class
    declaring the event has access to the storage. Just as with a property,
    code outside the class is forced to go through the accessor methods (add
    and remove for events), and cannot modify the underlying delegate
    directly. Simply using a delegate would not accomplish this.

    Pete

    Comment

    • puzzlecracker

      #3
      Re: Why events if we have delegates

      On Oct 28, 1:54 pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
      wrote:
      On Tue, 28 Oct 2008 09:57:08 -0700, puzzlecracker <ironsel2...@gm ail.com> 
      wrote:
      >
      I took a closer look at delegates and events, and it became apparent
      that events don't offer any extra functionalities over delegates. I
      don't even see it as syntactical sugar over "overtly obfuscated"
      delegate syntax. Moreover, you can accomplish everything with
      delegates that you can accomplish with events, such as combining
      instances, etc.
      >
      Am  I missing something  here?
      >
      Yes.  You are missing the fact that if you use a delegate, you are forced  
      to use the delegate's mechanism for adding and removing method groups.  If  
      you write an event, you have the ability to manage the subscription  
      however you like.  For example, the Control class maintains a dictionary  
      for each event.  There's a little overhead for the dictionary, but there's  
      _zero_ storage for each event unless it's actually subscribed.  For a  
      class like Control (and its subclasses) that have a huge number of events 
      that are almost never subscribed to, this is a very significant memory  
      savings.
      Is there a sample implementation of events stored in dictionary to
      save memory? It's sounds like an interesting approach, even though
      it's unrelated to the question itself, thought it may become clearer
      to me when I see the example, a good one.
      The other thing you're missing is that an event _encapsulates_ the  
      delegate.  That is, while the semantics are similar, only the class  
      declaring the event has access to the storage.  Just as with a property,  
      code outside the class is forced to go through the accessor methods (add  
      and remove for events), and cannot modify the underlying delegate  
      directly.  Simply using a delegate would not accomplish this.
      So it is meant for a user to prevent exposing the delegate instance to
      the event? So events becomes just an anonymous placeholder for a
      delegate.

      Thanks

      Comment

      • qglyirnyfgfo@mailinator.com

        #4
        Re: Why events if we have delegates

        Is there a sample implementation of events stored in dictionary to
        save memory?  It's sounds like an interesting approach, even though
        it's unrelated to the question itself, thought it may become clearer
        to me when I see the example, a good one.
        I think "Exaple 2" on link http://msdn.microsoft.com/en-us/libr...ea(VS.71).aspx
        So it is meant for a user to prevent exposing the delegate instance to
        the event? So events becomes just an anonymous placeholder for a
        delegate.
        Create a project where you declare an event and use Reflector to see
        what is happening behind the scenes. What you will see is that the
        even gets translated into two functions used to add and remove
        subscriptions.

        That is why you can have event declarations on an Interface, because
        behind the scenes, the interface will have a get and set method as the
        event definition.

        Comment

        • xcal

          #5
          Re: Why events if we have delegates

          delegates are references to methods,
          you need some mechanisms to trigger delegates

          "puzzlecrac ker" <ironsel2000@gm ail.comwrote in message
          news:160a3fd4-216e-40f4-9a59-ffc1e3a51c56@a2 9g2000pra.googl egroups.com...
          I took a closer look at delegates and events, and it became apparent
          that events don't offer any extra functionalities over delegates. I
          don't even see it as syntactical sugar over "overtly obfuscated"
          delegate syntax. Moreover, you can accomplish everything with
          delegates that you can accomplish with events, such as combining
          instances, etc.
          >
          Am I missing something here?
          >
          Thanks

          Comment

          • Peter Duniho

            #6
            Re: Why events if we have delegates

            On Tue, 28 Oct 2008 13:30:51 -0700, puzzlecracker <ironsel2000@gm ail.com>
            wrote:
            Is there a sample implementation of events stored in dictionary to
            save memory? It's sounds like an interesting approach, even though
            it's unrelated to the question itself, thought it may become clearer
            to me when I see the example, a good one.
            I'm not sure what you mean by "unrelated to the question itself". In that
            an event is an abstraction that need not be implemented using a simple
            delegate field, I think your follow-up is in face reasonably related to
            the original question.

            As for such an example, here's a sort of brain-dead version of what it
            might look like:

            class Base
            {
            Dictionary<stri ng, Delegate_dictEv entHandlers = new
            Dictionary<stri ng, Delegate>();

            protected void _AddEventHandle r(string strEventName, Delegate
            handler)
            {
            Delegate handlerCur;

            if (_dictEventHand lers.TryGetValu e(strEventName, out
            handlerCur))
            {
            handlerCur += handler;
            }
            else
            {
            handlerCur = null;
            }

            _dictEventHandl ers[strEventName] = handlerCur;
            }

            protected void _RemoveEventHan dler(string strEventName, Delegate
            handler)
            {
            Delegate handlerCur;

            if (_dictEventHand lers.TryGetValu e(strEventName, out
            handlerCur))
            {
            handlerCur -= handler;
            _dictEventHandl ers[strEventName] = handlerCur;
            }
            }

            public event EventHandler BaseEvent
            {
            add { _AddEventHandle r("BaseEvent" , value); }
            remove { _RemoveEventHan dler("BaseEvent ", value); }
            }
            }

            class Derived : Base
            {
            public event EventHandler DerivedEvent
            {
            add { _AddEventHandle r("DerivedEvent ", value); }
            remove { _RemoveEventHan dler("DerivedEv ent, value); }
            }
            }

            I say "brain-dead" because using a string as the key for the dictionary
            isn't the most efficient approach a class like this might take. But it's
            simple, and actually doesn't add _that_ much overhead.

            Anyway, hopefully the example is sufficient to illustrate the idea. Note
            that unless an event is actually subscribed to, the dictionary never winds
            up storing anything for that actual event. The approach itself has some
            overhead, in the form of the dictionary itself (which even when empty,
            takes up _some_ room), and of course the keys (which even if they are
            Guids or something like that, take up some space in the executable). But
            not that the keys are not per-instance, and if you've got lots of events,
            the space taken by the dictionary itself is tiny compared to how big an
            instance would be to store all those null references that are almost never
            used if the default implementation was used.

            >The other thing you're missing is that an event _encapsulates_ the  
            >delegate.  That is, while the semantics are similar, only the class  
            >declaring the event has access to the storage.  Just as with a
            >property,  
            >code outside the class is forced to go through the accessor methods
            >(add  
            >and remove for events), and cannot modify the underlying delegate  
            >directly.  Simply using a delegate would not accomplish this.
            >
            So it is meant for a user to prevent exposing the delegate instance to
            the event? So events becomes just an anonymous placeholder for a
            delegate.
            I don't know what you mean by "anonymous placeholder". They're neither
            anonymous nor just a placeholder. They are named, and they have actual
            implementation behind them. It's just that, just like a property does, an
            event creates an encapsulation of functionality that hides the underlying
            implementation from the user code.

            It's basically a type of interface or data contract if you will. An event
            promises to the user certain semantics -- add and remove -- along with a
            specific data type (whatever delegate type is used for the event). That's
            _all_ the user is promised, and inside the event implementation, the class
            is free to implement it however they like.

            Now, just as in C# 3.0 there are automatic properties, events in C# have
            an automatic, or default, implementation in which the compiler creates the
            add and remove methods for you, as well as a private field for storing the
            state of the event.

            Unlike the case with automatic properties, for an automatic event the
            class declaring the event still needs to be able to distinguish between
            the event itself and the field storing the state, because the event itself
            can't be read. So it's a _little_ different from a property in that
            respect; when the declaring class uses the event name, it gets the field,
            but when any other code uses the event name, it gets the event itself.

            But other than that, if you understand why properties are useful, you
            should also understand why the similar encapsulation an event provides is
            useful.

            Pete

            Comment

            Working...