tags:

views:

204

answers:

4

What purpose do protected or private (non-static) events in .NET really serve?

It seems like any private or protected event is more easily handled via a virtual method. I can (somewhat) see the need for this in static events, but not for normal events.

Have you had a use case before that clearly demonstrates a need or advantage for a non-static protected or private event?

+6  A: 

Seems to me that a good example of where a private event is useful is in component/control building, often you may have a component that is a composite of 1 or more other components, private events that contained components can subscribe to is a handy and easy implementation of an observer pattern.

Edit:

Let me give an example...

Say you are writing a Grid type control, and inside of this control you would most likely have a bunch of contained classes that are created dynamically Rows, Cols, headers etc for example, say you want to notify these contained classes that something they care about has happend, say a Skinning change or something like that, something that you don't necesarrily want to expose as an event to the grid users, this is where private events are handy, simply have one or 2 handlers and as you create each instance of your row or col or whatever attach the handler, as otherwise you just have to write your own observer mechanism, not hard, but why when you dont have to and you can just use multicast events.

Tim Jarvis
For the component to work, wouldn't the individual elements need to have public (or at least internal) events? How is the "composite component" going to subscribe to a private or protected event on it's part(s)?
Reed Copsey
The contained classes are just that, contained, so they are in the scope of the class defining the private event.
Tim Jarvis
Oh, you're thinking specifically of a component defined as a nested class, then?
Reed Copsey
Yeah, thats a pretty common use case for private events.
Tim Jarvis
I'm marking this as the answer - since it's the best example of a use that seems practical in the current version of .NET.
Reed Copsey
+6  A: 

Here's a slightly bizarre but real-world scenario I implemented once. You have machine-generated and user-generated halves of a partial class. The machine-generated half contains code which wishes to inform the user-generated half when some event occurs. But the user-generated half might not care to do anything, or it might care to do rather a lot. It seems rude of the machine-generated half to require that the user-generated half implement a particular method in order to handle a message they don't have any interest in listening to.

To solve this problem, the machine-generated half could fire on a private event. If the user-generated half cares, it can subscribe the event. If not, it can ignore it.

This scenario is now addressed more elegantly by partial methods in C# 3, but that was not an option back in the day.

Eric Lippert
Very interesting, although I agree partial methods are probably a more interesting option in the current platform.
Reed Copsey
Incidentally, when we first designed that architecture VB did not actually support listening to your own events. I believe it does now.
Eric Lippert
+1  A: 

Nested types have access to the enclosing type's private and protected events. I've used this feature to notify child controls (the nested type) of state changes in the parent control (the enclosing type) in a Silverlight application.

Ben M
A: 

Sorry to drag up an old thread, but I use private events with impunity in one of my projects, and personally, I find it's a good way of solving a design issue:

Here's the abbreviated code:

public class MyClass
{
  private event EventHandler _myEvent;

  public ExternalObject { get; set; }

  public event EventHandler MyEvent
  {
    add
    {
      if (_myEvent.GetInvocationList().Length == 0 && value != null)
        ExternalObject.ExternalEvent += HandleEvent;
      _myEvent+= value;
    }
    remove
    {
      _myEvent-= value;
      if (_myEvent.GetInvocationList().Length == 0)
        ExternalObject.ExternalEvent -= HandleEvent;
    }
  }

  private void HandleEvent(object sender, EventArgs e)
  {
     _myEvent.Raise(this, EventArgs.Empty); // raises the event.
  }
}

Basically, MyEvent is only ever raised in the event handler of ExternalObject.ExternalEvent, so if there's no handlers for MyEvent then I don't need to attach a handler to the external event, speeding up the code slightly by saving a stack frame.

Flynn1179