Events - naming convention and style

后端 未结 7 688
北海茫月
北海茫月 2020-12-02 10:40

I\'m learning about Events / Delegates in C#. Could I ask your opinion on the naming/coding style I\'ve chosen (taken from the Head First C# book)?

Am teaching a fr

7条回答
  •  庸人自扰
    2020-12-02 11:05

    There are a few points that I would mention:

    Metronome.OnTick doesn't seem to be named correctly. Semantically, "OnTick" tells me it will be called when it "Tick"s, but that isn't really what's happening. I would call it "Go" instead.

    The typically accepted model, however would be to do the following. OnTick is a virtual method that raises the event. This way, you can override the default behavior in inherited classes easily, and call the base to raise the event.

    class Metronome
    {
        public event EventHandler Tick;
    
        protected virtual void OnTick(EventArgs e)
        {
            //Raise the Tick event (see below for an explanation of this)
            var tickEvent = Tick;
            if(tickEvent != null)
                tickEvent(this, e);
        }
    
        public void Go()
        {
            while(true)
            {
                Thread.Sleep(2000);
                OnTick(EventArgs.Empty); //Raises the Tick event
            }
        }
    }
    

    Also, I know this is a simple example, but if there are no listeners attached, your code will throw on Tick(this, EventArgs.Empty). You should at least include a null guard to check for listeners:

    if(Tick != null)
        Tick(this, EventArgs.Empty);
    

    However, this is still vulnerable in a multithreaded environment if the listener is unregistered between the guard and the invocation. The best would be to capture the current listeners first and call them:

    var tickEvent = Tick;
    if(tickEvent != null)
        tickEvent(this, EventArgs.Empty);
    

    I know this is an old answer, but since it's still gathering upvotes, here's the C# 6 way of doing things. The whole "guard" concept can be replaced with a conditional method call and the compiler does indeed do the Right Thing(TM) in regards to capturing the listeners:

    Tick?.Invoke(this, EventArgs.Empty);
    

提交回复
热议问题