Каковы правила именования параметров типа?
Я заметил, а также увидел в Essential С# 3.0, что параметры обычно определяются как T или TEntity
Например:
public class Stack<T>
{
}
или
public class EntityCollection<TEntity>
{
}
Как вы решаете, какое имя использовать?
Спасибо
Ответы
Ответ 1
Вот мой набор правил
- Если есть один параметр, я называю его T
- Если имеется более одного параметра, я выбираю значащее имя и префикс с T. Например, TKey, TValue
Для полуофициального мнения стоит взглянуть на руководящие принципы рамочного проекта по этому вопросу:
Ответ 2
Я извлек исходный код .NET Framework 4.6 из http://referencesource.microsoft.com/dotnet46.zip. Извлеките его и обработайте данные, чтобы извлечь имя универсального параметра из всех объявлений общего класса.
Примечание. Я только извлек общее имя параметра из общих классов только с одним общим параметром. Таким образом, это не учитывает общие классы с несколькими типичными параметрами.
grep -nohrP "class \w+<T\w*>" | sed -e 's/.*\<//' -e 's/>//' | sort | uniq -cd | sort -bgr
Результат:
361 T
74 TChannel
51 TKey
33 TResult
30 TSource
28 T_Identifier
18 TElement
12 TEntity
11 TInputOutput
7 TItem
6 TLeftKey
6 TFilterData
5 T_Query
4 T_Tile
4 TInput
3 TValue
3 TRow
3 TOutput
3 TEventArgs
3 TDataReader
3 T1
2 TWrapper
2 TVertex
2 TValidationResult
2 TSyndicationItem
2 TSyndicationFeed
2 TServiceType
2 TServiceModelExtensionElement
2 TResultType
2 TMessage
2 TLocationValue
2 TInnerChannel
2 TextElementType
2 TException
2 TEnum
2 TDuplexChannel
2 TDelegate
2 TData
2 TContract
2 TConfigurationElement
2 TBinder
2 TAttribute
Ответ 3
В конце концов, это НЕ ДЕЙСТВИТЕЛЬНО. Используйте соглашение об именах, которое имеет смысл.
public class MyDictionary<T1, T2>
{ }
вероятно, не так полезен, как
public class MyDictionary<KeyType, ValueType>
(или TKey, TValue, если хотите).
Если я смотрю на вашу реализацию и должен думать "хорошо, что это за" T3 "снова?" то вы не сделали хорошую работу.
Ответ 4
Есть несколько вещей, которые, я думаю, вы должны учитывать:
- Сколько аргументов типа существует?
- Существуют ли какие-либо ограничения на них?
- Используются ли они для чего-то особенного?
В общем, я всегда префишу свои аргументы типа T
и делаю их "достаточно описательными", что означает как описательный, поскольку они должны быть для меня, чтобы понять, что они делают, и/или того, что от них требуется, когда я смотрю на код через полгода.
Несколько примеров, на мой взгляд, хорошее именование аргументов типа (нумерация в этом списке не зависит от нумерации выше...):
-
Один аргумент, и это очевидно из имени класса (или иначе из контекста в коде), почему требуется имя типа:
List<T>
Так как мы можем видеть, что это список объектов типа T
, и нет специальных ограничений на T
, нет необходимости указывать более конкретное имя для аргумента типа.
-
Несколько аргументов, которые представляют разные вещи в общем классе/интерфейсе:
IDictionary<TKey, TValue>
Нам нужно уметь различать два аргумента, поэтому мы не предоставляем тип ключа для значения и наоборот. Таким образом, назначение аргументов Key
и Value
и префиксов с помощью T
представляется подходящим.
Я должен подчеркнуть, что это намного лучше, чем, например, IDictionary<T1, T2>
или IDictionary<T, U>
, поскольку в последних двух случаях нет возможности интуитивно узнать, какой аргумент будет использоваться для чего.
-
Один аргумент типа, но тип должен соответствовать некоторым требованиям:
Repository<TEntity> where TEntity : class, IEntity
Так как мы требуем, чтобы тип реализовал другой интерфейс, имеет смысл дать некоторые хедз-ап программисту, что это так. Выберите некоторое информативное имя, которое поможет вам узнать, что требуется от этого типа, и префикс его с помощью T
.
Ответ 5
Пример из Microsoft:
public interface IDictionary<TKey, TValue>
Параметр type представляет что-то, поэтому, если вы хотите иметь читаемый код, это "что-то" должно быть очевидно из кода (без дополнительных комментариев). Использование имен типов, таких как T, V, U, не обязательно очевидно (но иногда это может быть).
Ответ 6
Я не знаю никаких твердых соглашений для дженериков.
Образцы, которые я видел, используют одно из вариантов ff:
-
T
для параметров одного типа
-
K
для второго параметра типа U
для третьего, например, SomeGeneric<T, K, U>
-
T
и число для параметра второго и третьего типа, например SomeGeneric<T1, T2, T3>
Я думаю, что генерики являются достаточно новыми, что общие отраслевые соглашения еще не установлены.
Ответ 7
Я просмотрел все ответы до сих пор, и я думаю, что они все частично правы, но не полностью учитывают все ситуации.
Мое мнение состоит в том, что именование должно всегда добавлять контекстуальное значение. Таким образом, именование параметра типа TEntity
, потому что его тип IEntity
будет неправильным, особенно если ограничение показывает его тип, и это показано в IntelliSense. Это было бы похоже на именование строковой переменной _string
. В современном программировании мы просто этого не делаем. Имена переменных должны отражать их функциональную роль. Параметры типа не должны отличаться.
В случае одного параметра типа контекст обычно должен быть очевиден в терминах класса, поэтому T
в порядке. Для параметров нескольких типов добавьте описательный контекст к каждому из них, например TKey
и TValue
. Это еще одна причина, по которой типы не должны использоваться - что, если оба параметра типа одного типа? TEntity1
и TEntity2
?
Если существуют ограничения с именами типов, которые добавляют желаемый контекст, тогда приемлемо использовать T
, U
и т.д. или T1
, T2
и т.д., так как само ограничение показывает контекст, не говоря уже о IntelliSense.
Итак, мой ответ аналогичен ответам JaredPar и Tomas Lycken, но с добавленной квалификацией и, в частности, исключает третье правило Tomas Lycken, где вместо T
следует использовать в случае параметров одного типа с ограничением (из-за класса контекст и IntelliSense).