Каковы правила именования параметров типа?

Я заметил, а также увидел в 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).