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.