Share via


Popular patterns around events?

In Properties with events: another attempt, Omer said:

I would rather have a protected virtual OnSet method and AfterSet event than just an OnSet event (also consistant with the naming convention ;).

I know understand that this is a common pattern found in .Net, which I didn’t know before.

As you’ve probably noticed in my blogs, I like to take a pattern or guidance and stuff it into a class. My hope is to improve clarity of code & reduce duplication. That’s what I’m trying to do here with events

I read an article at CodeProject, and came up with the code below.

I’ve also read Microsoft’s guidelines, which I conflict with pretty heavily. However, I haven’t yet found a way to reconcile the differences.

(I applied the idea of breaking the class with partial types. Some folks use #region for the same purpose.)

Here’s what I have so far:

      // more types

      partial class MyEvent

      {

            // MS guidelines say "Name an event argument class with the EventArgs suffix"

            //

            // The full name of this type is "MyEvent.Args", which seems to match the

            // guidance

            public class Args : System.EventArgs

            {

                  public Args(string text) { this.Text = text; }

                  public readonly string Text;

            }

            // MS guidelines say "Use an EventHandler suffix on event handler names."

            //

            // The full name of this type is "MyEvent.Handler", which seems to match

            // the guidance.

            public delegate void Handler(object sender, Args e);

      }

      // events

      partial class MyEvent

      {

            // MS guidelines say "Consider naming events with a verb. "

            //

            // What verb? Or should the class 'MyEvent' be named with

            // a verb? Or the instance of the class?

            // MS guidelines say "Use a gerund to create an event name that

            // expresses the concept of pre-event, and a past-tense verb to represent

            // post-event. ... Do not use the BeforeXxx/AfterXxx naming pattern."

            //

            // But what to call it? Pre and Post?

            public event Handler Before = delegate { };

            public event Handler After = delegate { };

      }

      // Overridable methods

      partial class MyEvent

      {

            protected virtual void OnBefore(Args e)

            {

                  this.Before(this, e);

            }

            protected virtual void OnAfter(Args e)

            {

                  this.After(this, e);

            }

      }

      // Public API

      partial class MyEvent

      {

            Args _e;

            public IDisposable Open(Args e)

            {

                  this._e = e;

                  this.OnBefore(e);

return this;

            }

            public void Close()

            {

                  this.OnAfter(_e);

this.DebugOnDispose();

}

      }

      // IDisposable

      partial class MyEvent : IDisposable

      {

            void IDisposable.Dispose()

            {

                  this.Close();

            }

      }

      // DEBUG verification

      partial class MyEvent

      {

            [Conditional("DEBUG")]

            void DebugOnDispose()

            {

                  GC.SuppressFinalize(this);

            }

            // You can't put a Conditional attribute on a destructor!

            // [Conditional("DEBUG")]

#if DEBUG

            ~MyEvent()

            {

                  Debug.Fail("MyEvent was not properly disposed");

            }

#endif

      }

 

Edit: Fixed a few bugs in the original code.  Todo: Add 'public IDisposable IDisposable { get { return this; } }', and an example of how this class is to be used.

Comments

  • Anonymous
    July 01, 2004
    Shouldn't you start with how to use the class, then code it?
  • Anonymous
    July 01, 2004
    I am failing to understand the Open semantics where you return an IDisposable. You have to new a MyEvent class in order to call Open() or did you mean for this to be static?

    I haven't looked into partial classes to much yet so this surprised me
    partial class MyEvent : IDisposable

    Would you then use your own event class in place of the System.Event? I haven't spent any time thinking about it, but what would this do to your usability/interoperability with other areas?
  • Anonymous
    July 01, 2004
    Thomas: Many smart people keep saying what you've said, but I just won't listen...

    Once I figure out how it should be used, I'll write it down LOL.
  • Anonymous
    July 07, 2004
    Comment on using the naming conventions:Should Args not be MyEventArgs
  • Anonymous
    July 08, 2004
    Dirc: Perhaps it should be.

    The official guidance would have me create a global class called "MyEventArgs". But when I see that name and "MyEvent", I see duplication that I want to remove.

    So, I move MyEventArgs to be a nested type inside MyEvent. Now the full name is "MyEvent.Args". That's only one character different than the recommnended name, and it's a very small character indeed!

    See also http://blogs.msdn.com/jaybaz_ms/archive/2004/07/02/172144.aspx for an updated version of this class which I like a great deal more.