Правильное соглашение об именах для типа делегата .NET?

83

По соглашению классы часто называются существительными, методы - глаголами, а интерфейсы - прилагательными.

Какое общее соглашение об именах для делегата? Или как лучше отличить его имя, когда делегаты перечислены среди типов и других вещей?

Мое непосредственное предположение состоит в том, чтобы называть делегата, скорее, прилагательным, потому что интерфейс единственного метода часто можно заменить делегатом.

Некоторые мысли:

delegate object ValueExtracting(object container);

delegate object ValueExtractor(object container);

delegate object ValueExtractionHandling(object container);

delegate object ValueExtractionHandler(object container);
Джон К
источник

Ответы:

112

Лично я использую несколько разных паттернов:

[Task][State]Handler - UITaskFinishedHandler

[Event]Handler - ControlLoadedHandler

[Function Name]Delegate - DoSomeWorkDelegate - используется, когда мне нужно создать делегата для вызова функции в другом / новом потоке

[Task]Callback - ContainerLoadedCallback - используется, когда элемент управления A запускает действие, в котором элемент B выполняет большую часть работы, а элемент управления A передал зависимость элементу B (т.е. ControlA, возможно, передал контейнер пользовательского интерфейса для ControlB для заполнения, и ему требуется уведомление, чтобы фактически показать контейнер. )

Когда у вас есть проект, который использует много многопоточных или асинхронных вызовов WCF, вы можете получить много плавающих делегатов, поэтому важно принять стандарт, который, по крайней мере, имеет для вас смысл.

слизняк
источник
+1 Хорошая конвенция. Я также согласен с ответом @Aaronaught ниже, где делегат, использующий тип события, должен иметь суффикс EventHandler, а не просто Handler.
Samuel
1
«[Имя функции] Делегат», к сожалению, нарушает CA1711. Мне нравится использовать «[Имя функции] Func» или «[Имя функции] Действие» в зависимости от того, имеет он возвращаемый тип или нет.
Tinister 05
1
Это, вероятно, самое полезное (и самое короткое) соглашение, которое я когда-либо видел. +1 от меня. Спасибо, что поделились @slugster
FullStackForger
Правила кода говорят вам не добавлять к
Кристиан Финдли,
3
@MelbourneDeveloper говорят, что ребята, которые создали RequestDelegateдля asp.net-core; -]
t3chb0t
48

В руководстве Microsoft Framework Design Guidelines - альманахе именования для меня - говорится следующее по теме:

√ ОБЯЗАТЕЛЬНО добавляйте суффикс EventHandler к именам делегатов, которые используются в событиях.
√ ОБЯЗАТЕЛЬНО добавляйте суффикс «Обратный вызов» к именам делегатов, кроме тех, которые используются как обработчики событий.
X НЕ ДОБАВЛЯЙТЕ суффикс «Delegate» к делегату.

Борислав Иванов
источник
16
Забавно, что MS говорит: «НЕ добавляйте суффикс« Delegate »к делегату», но в этом примере у них есть делегат с именем ProcessBookDelegate...
PadawanLondon
1
@PadawanLondon та же история с RequestDelegateasp.net-core - так много о согласованности и соглашениях по кодированию. Думаю, они даже свои документы не читают.
t3chb0t
16

Поскольку делегат - это то, что выполняет действие (глагол), делегат должен называться так, как вы бы назвали то, что выполняет это действие. Взять, Converter<TInput, TOutput>к примеру. Глагол - преобразовать . То, что выполняет преобразование, называется конвертером , отсюда и название делегата.

Кевин Киблер
источник
6

Это зависит от нескольких вещей.

Если делегат будет использоваться как событие, его всегда следует называть EventHandlerподтипом, например:

public delegate void ValueExtractingEventHandler(object sender,
    ValueExtractingEventArgs e);

Если это не событие, то MS кодирования руководящих принципов (которые я никогда не могу показаться , чтобы найти правильную копию на Google) явно рекомендовать против включая такие слова , как «делегат» или «обработчик» во имени делегата, за исключением того, в частном случае EventHandlerтипы.

Обычно делегаты должны быть названы в честь действий , например ValueExtracting(если делегат происходит до извлечения значения) или ValueExtracted(после извлечения).

Func<T1, T2, ..., TResult>Синтаксис делегат также становится все более распространенным, но если у вас есть 4 или более параметров , идущие в нее, вам не нужно объявлять свои собственные вообще - просто использовать существующий:

object ExtractObject(object source, Func<object, object> extractor);

Этот синтаксис лучше всего подходит, когда делегат используется как закрытие . Сам делегат не имеет очень интересного имени, но аргумент - это существительное агента (экстрактор, поставщик, оценщик, селектор и т. Д.)

Большинство случаев использования делегата попадает в одну из вышеперечисленных категорий, поэтому выясните, для какой из них он используется, и выберите соответствующий вариант.

Aaronaught
источник
3

Я никогда не думал об этом, в основном , потому что я просто использовать один из EventHandler<T>, Func<T>или Action<T>перегрузок и никогда не беспокоить определения моих. Я бы, наверное, выбрал ValueExtractor из перечисленных вами. Это делает его более похожим на объект, и когда вы его вызываете, вы будете использовать этот объект для выполнения действия. Например:

ValueExtractor extractor += Blah;
var value = extractor(data);

Кроме того, большинство встроенных делегатов также называются существительными. В случае сомнений используйте платформу .NET.

MikeP
источник
0

Я бы выбрал ValueExtraction ...
Никогда не думал, почему, но я думаю, потому что вы храните операцию, и это должно быть существительное ... строго, это не операция, я знаю ...

Матиас
источник
0

Исходя из этого Enumerable.Sum, я бы передал делегату как a Func<object, object>и назвал параметр selector:

void Foo(Func<object, object> selector) ...

Если вам нужно создать для него своего собственного представителя, я бы выбрал его, ValueExtractorпоскольку это наиболее наглядное название того, что он делает.

Сэм Харвелл
источник
Эти универсальные делегаты (Action и Func) подходят в 95% случаев. Однако есть некоторые случаи, когда их явно недостаточно - это когда делегат имеет сложную подпись и часто передается. По сути, то, что делает каждый аргумент, должно быть очевидным, если это не так, создание именованного делегата - хорошая идея.
Matěj Zábský
0

В случае событий (с делегатами) Windows Forms использует следующее соглашение:

Делегат:

public delegate void MouseEventHandler(object sender, MouseEventArgs e);

Событие:

public event MouseEventHandler MouseClick;

Слушатель событий:

this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
дан
источник