Я заметил, а также увидел в Essential С# 3.0, что параметры обычно определяются как T или TEntity
Например:
public class Stack<T>
{
}
или
public class EntityCollection<TEntity>
{
}
Как вы решаете, какое имя использовать?
Спасибо
Я заметил, а также увидел в Essential С# 3.0, что параметры обычно определяются как T или TEntity
Например:
public class Stack<T>
{
}
или
public class EntityCollection<TEntity>
{
}
Как вы решаете, какое имя использовать?
Спасибо
Вот мой набор правил
Для полуофициального мнения стоит взглянуть на руководящие принципы рамочного проекта по этому вопросу:
Я извлек исходный код .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
В конце концов, это НЕ ДЕЙСТВИТЕЛЬНО. Используйте соглашение об именах, которое имеет смысл.
public class MyDictionary<T1, T2>
{ }
вероятно, не так полезен, как
public class MyDictionary<KeyType, ValueType>
(или TKey, TValue, если хотите).
Если я смотрю на вашу реализацию и должен думать "хорошо, что это за" T3 "снова?" то вы не сделали хорошую работу.
Есть несколько вещей, которые, я думаю, вы должны учитывать:
В общем, я всегда префишу свои аргументы типа T и делаю их "достаточно описательными", что означает как описательный, поскольку они должны быть для меня, чтобы понять, что они делают, и/или того, что от них требуется, когда я смотрю на код через полгода.
Несколько примеров, на мой взгляд, хорошее именование аргументов типа (нумерация в этом списке не зависит от нумерации выше...):
Один аргумент, и это очевидно из имени класса (или иначе из контекста в коде), почему требуется имя типа:
List<T>
Так как мы можем видеть, что это список объектов типа T, и нет специальных ограничений на T, нет необходимости указывать более конкретное имя для аргумента типа.
Несколько аргументов, которые представляют разные вещи в общем классе/интерфейсе:
IDictionary<TKey, TValue>
Нам нужно уметь различать два аргумента, поэтому мы не предоставляем тип ключа для значения и наоборот. Таким образом, назначение аргументов Key и Value и префиксов с помощью T представляется подходящим.
Я должен подчеркнуть, что это намного лучше, чем, например, IDictionary<T1, T2> или IDictionary<T, U>, поскольку в последних двух случаях нет возможности интуитивно узнать, какой аргумент будет использоваться для чего.
Один аргумент типа, но тип должен соответствовать некоторым требованиям:
Repository<TEntity> where TEntity : class, IEntity
Так как мы требуем, чтобы тип реализовал другой интерфейс, имеет смысл дать некоторые хедз-ап программисту, что это так. Выберите некоторое информативное имя, которое поможет вам узнать, что требуется от этого типа, и префикс его с помощью T.
Пример из Microsoft:
public interface IDictionary<TKey, TValue>
Параметр type представляет что-то, поэтому, если вы хотите иметь читаемый код, это "что-то" должно быть очевидно из кода (без дополнительных комментариев). Использование имен типов, таких как T, V, U, не обязательно очевидно (но иногда это может быть).
Я не знаю никаких твердых соглашений для дженериков.
Образцы, которые я видел, используют одно из вариантов ff:
T для параметров одного типаK для второго параметра типа U для третьего, например, SomeGeneric<T, K, U>T и число для параметра второго и третьего типа, например SomeGeneric<T1, T2, T3>Я думаю, что генерики являются достаточно новыми, что общие отраслевые соглашения еще не установлены.
Я просмотрел все ответы до сих пор, и я думаю, что они все частично правы, но не полностью учитывают все ситуации.
Мое мнение состоит в том, что именование должно всегда добавлять контекстуальное значение. Таким образом, именование параметра типа TEntity, потому что его тип IEntity будет неправильным, особенно если ограничение показывает его тип, и это показано в IntelliSense. Это было бы похоже на именование строковой переменной _string. В современном программировании мы просто этого не делаем. Имена переменных должны отражать их функциональную роль. Параметры типа не должны отличаться.
В случае одного параметра типа контекст обычно должен быть очевиден в терминах класса, поэтому T в порядке. Для параметров нескольких типов добавьте описательный контекст к каждому из них, например TKey и TValue. Это еще одна причина, по которой типы не должны использоваться - что, если оба параметра типа одного типа? TEntity1 и TEntity2?
Если существуют ограничения с именами типов, которые добавляют желаемый контекст, тогда приемлемо использовать T, U и т.д. или T1, T2 и т.д., так как само ограничение показывает контекст, не говоря уже о IntelliSense.
Итак, мой ответ аналогичен ответам JaredPar и Tomas Lycken, но с добавленной квалификацией и, в частности, исключает третье правило Tomas Lycken, где вместо T следует использовать в случае параметров одного типа с ограничением (из-за класса контекст и IntelliSense).