Именование, объявление и определение делегатов и соглашений о событиях
Как вы называете делегаты, события и экземпляр событий?
Я использую это:
delegate void OnSomethingHandler();
event OnSomethingHandler onSomething;
Это приемлемый способ? Обратите внимание на нижний и верхний регионы
Где вы размещаете делегатов и события?
Я обычно помещаю делегатов в пространство имен, наилучшим образом отражающее их:
mynamespace.Def.SomethingLike
{
}
mynamespace.Def.SomethingElseLike
{
}
Где вы определяете события?
Я обычно помещаю их в класс, который их использует.
Я замечаю, что многие люди определяют делегаты и события в одном классе. Насколько распространено это?
Ответы
Ответ 1
Все, что у вас есть, выглядит довольно стандартно - единственное, что я бы изменил, это то, что имя события будет Something
, а не onSomething
. Следуя соглашению Microsoft, у вас получилось бы нечто подобное:
delegate void SomethingHandler();
event SomethingHandler Something;
protected void OnSomething()
{
if (this.Something != null)
this.Something();
}
И как классный трюк, вы можете добавить пустой делегат в свое событие Something
, чтобы вам не нужно было проверять событие для null, прежде чем его поднять:
delegate void SomethingHandler();
event SomethingHandler Something = delegate {};
protected void OnSomething()
{
this.Something();
}
Ответ 2
MSDN при именовании событий:
События всегда относятся к какому-либо действию, которое происходит или которое произошло. Поэтому, как и в случае с методами, события называются с глаголами, а время глагола используется для указания времени, когда событие поднимается.
√ DO назвать события с помощью глагола или глагольной фразы.
Примеры включают Clicked
, Painting
, DroppedDown
и т.д.
√ DO дает имена событий с концепцией до и после, используя текущие и прошлые времена.
Например, событие закрытия, которое возникает перед закрытием окна, будет называться Closing
, а одно, которое создается после закрытия окна, будет называться Closed
.
X НЕ НЕ используйте префикс или постфикс "До" или "После", чтобы указать пре- и пост-события. Используйте текущие и прошлые времена, как только что описано.
√ DO обработчики событий имен (делегаты, используемые как типы событий) с суффиксом "EventHandler", как показано в следующем примере:
public delegate void ClickedEventHandler(object sender, ClickedEventArgs e);
√ DO используйте два параметра с именем sender и e в обработчиках событий.
Параметр отправителя представляет объект, который поднял событие. Параметр отправителя обычно имеет тип object
, даже если можно использовать более конкретный тип.
√ DO классы аргументов имени события с суффиксом EventArgs.
Итак, события должны быть названы с глагольной или глагольной фразой. Вместо OnSomething
используйте Something
, считая, что Something
на самом деле является глаголом, например Close
, Click
или ManagedPiplelineAbandoning
и ManagedPiplelineAbandoned
.
Делегат для события должен быть назван суффиксом EventHandler
, указав CloseEventHandler
, ClickEventHandler
, ManagedPiplelineAbandoningHandler
и т.д.
Для делегатов, которые не связаны с событием, используйте существительное, например EventProcessor
или ItemRetriever
, а экземпляр этого делегата - это глагол, например processEvent
или retrieveItem
.
Корпус вашей ссылки делегата должен быть верблюдом, если ссылка не является частной. Я не могу придумать случай, когда у вас будет поле не-частного делегата.
Однако, поскольку предлагается использовать обычную сигнатуру обработчика событий (т.е. object sender, EventArgs e)
), вы должны использовать общий обработчик событий определения вашего собственного. То есть ваше событие будет определено как нечто подобное:
event EventHandler<SomethingEventArgs> Something;
Ответ 3
расширение на 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();
}
}
}