命名、声明和定义委托和事件的惯例

19

如何为委托、事件和事件实例命名?

我使用以下方式:

delegate void OnSomethingHandler();
event OnSomethingHandler onSomething;

这是一种被接受的方式吗?请注意大小写。


委托和事件应该放在哪里?

我通常将委托放在最能反映它们的命名空间中:

mynamespace.Def.SomethingLike
{

}
mynamespace.Def.SomethingElseLike
{

}

你在哪里定义事件?

我通常将它们放在使用它们的类中。

我注意到很多人将委托和事件定义在同一个类中。这有多常见?

3个回答

23

MSDN关于事件命名:

事件总是涉及到某些动作,无论是正在发生的还是已经发生的。因此,与方法一样,事件也使用动词进行命名,使用动词时态来指示事件被触发的时间。

应该使用动词或动词短语来命名事件。

例如,ClickedPaintingDroppedDown等。

应该使用现在时态和过去时态来为事件命名,体现前后概念。

例如,在窗口关闭之前引发的关闭事件应该被称为Closing,在窗口关闭之后引发的关闭事件应该被称为Closed

X 不要使用“Before”或“After”前缀或后缀来表示前/后事件。请如上所述使用现在时态和过去时态。

应该使用“EventHandler”后缀来为事件处理程序(在事件中用作类型的委托)命名,如以下示例所示:

public delegate void ClickedEventHandler(object sender, ClickedEventArgs e);

在事件处理程序中使用名为sendere的两个参数。

发送器参数表示引发事件的对象。发送器参数通常是object类型,即使可能要使用更具体的类型。

用"EventArgs"作为事件参数类的后缀来命名。

因此,事件应该以动词或动词短语命名。不要使用OnSomething,而是使用Something,假设Something实际上是一个动词,比如CloseClickManagedPiplelineAbandoningManagedPiplelineAbandoned

事件的委托应该以EventHandler后缀命名,例如CloseEventHandlerClickEventHandlerManagedPiplelineAbandoningHandler等。

对于与事件无关的委托,请使用一个名词,比如EventProcessorItemRetriever,而代表该委托的实例则是一个动词,比如processEventretrieveItem

你的委托引用应该采用驼峰命名法,除非该引用不是私有的。我想不到有哪种情况下会有非私有委托字段。

然而,由于建议使用传统的事件处理程序签名(即object sender, EventArgs e),因此你应该使用通用事件处理程序代替定义自己的事件处理程序。也就是说,你的事件应该定义为类似以下内容:

event EventHandler<SomethingEventArgs> Something;

17

你的代码看起来相当标准,唯一需要改变的是事件名称应该为Something而不是onSomething。遵循微软的约定,你的代码将更像这样:

delegate void SomethingHandler();
event SomethingHandler Something;

protected void OnSomething()
{
    if (this.Something != null)
        this.Something();
}

另一个很酷的技巧是,你可以向Something事件添加一个空的委托,这样在触发它之前就不必检查该事件是否为空:

delegate void SomethingHandler();
event SomethingHandler Something = delegate {};

protected void OnSomething()
{
    this.Something();
}

7
考虑在您的示例中包括SomethingEventArgs,因为它是约定的一部分。此外,在2.0之后,EventHandler<SomethingEventArgs>更常见。 - Richard Szalay

0

在 bdukes 的回答/总结基础上,结合我在这里找到的一个例子,这是我的尝试:

//from http://www.codeproject.com/Articles/11541/The-Simplest-C-Events-Example-Imaginable
using System;
namespace wildert
{
    public class TimeOfTickEventArgs : EventArgs //<- custom event args
    {
        private DateTime TimeNow;
        public DateTime Time
        {
            set { TimeNow = value; }
            get { return this.TimeNow; }
        }
    }
    public class Metronome
    {
        public delegate void TickEventHandler(object sender, TimeOfTickEventArgs e); //I put the delegate declaration before the events
        public event TickEventHandler Ticked; //Ticked(i.e. after something occurred), or possibly Ticking(i.e. before)

        public void Start()
        {
            while (true)
            {
                System.Threading.Thread.Sleep(3000);
                if (Ticked != null){
                    TimeOfTickEventArgs tot = new TimeOfTickEventArgs();
                    tot.Time = DateTime.Now;
                    Ticked(this, tot); //<- publish the event
                }
            }
        }
    }
    public class Listener
    {
        public void Subscribe(Metronome m){
            m.Ticked += new Metronome.TickEventHandler(HeardIt);  //<- subscribe to the event
        }
        private void HeardIt(object sender, TimeOfTickEventArgs e){ //<- this is the event handler (note signature 'object sender, xxx e')
            System.Console.WriteLine("HEARD IT AT {0}",e.Time);
        }
    }
    class Test
    {
        static void Main()
        {
            Metronome m = new Metronome();
            Listener l = new Listener();
            l.Subscribe(m);
            m.Start();
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,