1

A field-like-event is a way of declaring both a delegate variable and an event at the same time.

So a field like event (public event EventHandler MyEvent;) may translate to : ( taken from here)

private EventHandler _myEvent;

public event EventHandler MyEvent
{
    add
    {
        lock (this)
        {
            _myEvent += value;
        }
    }
    remove
    {
        lock (this)
        {
            _myEvent -= value;
        }
    }        
}

Notice private backup field.

However , I was corrected by Jon ( comments section) , that a general-event doen't have a backup field . something like :

 public event EventHandler MyEvent
    {
        add
        {
            Console.WriteLine ("add operation");
        }

        remove
        {
            Console.WriteLine ("remove operation");
        }
    }      

Notice - no backup field.

But then he said that winform act like this :

For instance, in situations where there are lots of events but only a few are likely to be subscribed to, you could have a map from some key describing the event to the delegate currently handling it. This is what Windows Forms does - it means that you can have a huge number of events without wasting a lot of memory with variables which will usually just have null values.

Question :

  • How can winform use this map thing to expose events without any backup field ( of delegate type)
Community
  • 1
  • 1
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • 1
    I note that you are showing the codegen for field-like events in C# 1, 2 and 3. In C# 4 we improved that codegen greatly; see http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx for details. – Eric Lippert May 04 '13 at 14:26
  • @EricLippert Does the fact that "_add and remove calls will be effectively serial_" can allow us to remove the lock ? ( if I understood the article correctly...) – Royi Namir May 04 '13 at 14:45
  • 1
    The lock is replaced by a lock-free atomic test-and-set that has the same effect as the lock as far as serializing access goes, but without the nasty side effect of locking `this`. The problem with locking `this` is that *someone else can lock it too*, and now you've made the correctness and efficiency of your event handling locking tied to the correctness and efficiency of everyone else who locks `this`. That's why it is a bad programming practice to lock `this`. – Eric Lippert May 04 '13 at 14:59

1 Answers1

2

First of all this "map thing" is just a Dictionary<object, EventHandler>. It is itself a field of the class however when it is created it will contain no elements and therefore not take up too much memory (just some overhead for its internal structures). As events are subscribed to delegates are added to the dictionary and we start to use more memory.

Consider a class with 50 events where we only use 5 events, in a simple scenario there would be 50 delegates created at for every instance of the class. When using a dictionary for storage there would be 5 delegates per instance.

P.S. This is the same principle behind Dependency Objects/Properties in WPF.

Slugart
  • 4,535
  • 24
  • 32
  • But the code ( in my second section) will still be 50 times in the document...no ? can you please supply a simple example so it will be clearer ? – Royi Namir May 04 '13 at 08:30
  • Check out Jon's answer here: http://stackoverflow.com/questions/5303595/what-are-some-cases-where-it-would-be-advantageous-to-use-an-event-without-havin – Slugart May 04 '13 at 08:50
  • 3
    You: _"there would be 50 delegates created"_ More precisely there would be 50 instance fields created whose values would consist of 45 null references and 5 references to instances. If the `Dictionary<,>` is used, there's one instance field which is a reference to a dictionary object which holds references to 5 string keys and 5 delegate values. – Jeppe Stig Nielsen May 04 '13 at 09:01