活动 - 命名规则和风格 [英] Events - naming convention and style

查看:106
本文介绍了活动 - 命名规则和风格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习活动/代表在C#。我可以问你的意见对我选择的命名/编码风格(从头部首先C#的书拍摄)?



我教这个,明天的朋友,和我试图想出解释概念的最优雅的方式。 (没想明白一个主题是,试图教它的最好办法!)

 类节目
{
静态无效的主要()
{
//设置节拍器,并确保EventHandler委托准备
节拍器节拍器=新节拍器();

//线了metronome_Tick方法EventHandler委托
监听器监听=新的侦听器(节拍器);
metronome.OnTick();
}
}




 公共类节拍器
{
//委托
//所以每一个节拍被调用时,运行时调用另一个方法
//在这种情况下Listener.metronome_Tick
公共事件的EventHandler蜱;

公共无效OnTick()
{
,而(真)
{
Thread.sleep代码(2000);
//因为使用EventHandler委托,需要我们虽然不使用它们
蜱(这一点,EventArgs.Empty)包括发送对象,EventArgs的
//;
}
}
}




 公共类监听器
{
公共侦听器(节拍器节拍器)
{
节拍器.Tick + =新的EventHandler(metronome_Tick);
}

私人无效metronome_Tick(对象发件人,EventArgs五)
{
Console.WriteLine(听到了);
}
}



n.b。代码是从 http://www.codeproject.com/KB/cs/simplesteventexample.aspx <重构/ p>

解决方案

有,我会提几个要点:



节拍器.OnTick似乎并没有被正确命名。语义上,OnTick告诉我,它会被称为时嘀S,但是这是不是真的发生了什么。我把它叫做走来代替。



通常接受的模型,但会做到以下几点。 OnTick 是引发事件的虚拟方法。通过这种方式,可以覆盖默认行为在继承的类很容易,并且调用基引发事件。

 类节拍器
{
公共事件的EventHandler蜱;

受保护的虚拟无效OnTick(EventArgs的发送)
{
//抬起Tick事件(见下面的这个解释)
VAR tickEvent =打勾;
如果(tickEvent!= NULL)
tickEvent(这一点,E);
}

公共无效围棋()
{
,而(真)
{
Thread.sleep代码(2000);
OnTick(EventArgs.Empty); //引发Tick事件
}
}
}






另外,我知道这是一个简单的例子,但是如果没有附加的听众,你的代码将抛出蜱(这一点,EventArgs.Empty)。你至少应该包括一个空警卫检查监听器:

 如果(!蜱= NULL)
蜱(对此,EventArgs.Empty);



不过,这仍然是在多线程环境脆弱,如果听者是后卫和调用之间未注册。最好的方法是首先捕获当前监听器,并呼吁他们:

  VAR tickEvent =打勾; 
如果(tickEvent!= NULL)
tickEvent(这一点,EventArgs.Empty);



我知道这是一个古老的答案,但因为它仍在收集upvotes,这里的C#6路做事。整个后卫的概念可以用一个条件方法调用所替换,编译器确实做正确的事(TM)的问候捕捉听众:

 勾选.Invoke(这一点,EventArgs.Empty)?; 


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 friend about this tomorrow, and am trying to come up with the most elegant way of explaining the concepts. (thought the best way to understand a subject is to try and teach it!)

class Program
    {
        static void Main()
        {
            // setup the metronome and make sure the EventHandler delegate is ready
            Metronome metronome = new Metronome();

            // wires up the metronome_Tick method to the EventHandler delegate
            Listener listener = new Listener(metronome);
            metronome.OnTick();
        }
    }


public class Metronome
    {
        // a delegate
        // so every time Tick is called, the runtime calls another method
        // in this case Listener.metronome_Tick
        public event EventHandler Tick;

        public void OnTick()
        {
            while (true)
            {
                Thread.Sleep(2000);
                // because using EventHandler delegate, need to include the sending object and eventargs 
                // although we are not using them
                Tick(this, EventArgs.Empty);
            }
        }
    }


public class Listener
    {
        public Listener(Metronome metronome)
        {
            metronome.Tick += new EventHandler(metronome_Tick);
        }

        private void metronome_Tick(object sender, EventArgs e)
        {
            Console.WriteLine("Heard it");
        }
    }

n.b. Code is refactored from http://www.codeproject.com/KB/cs/simplesteventexample.aspx

解决方案

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);

这篇关于活动 - 命名规则和风格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆