Каковы правила именования параметров типа? - PullRequest
18 голосов
/ 21 апреля 2009

Я заметил, а также увидел в книге Essential C # 3.0 , что параметры обычно определяются как T или TEntity

Например:

public class Stack<T>
{


}

или

public class EntityCollection<TEntity>
{


}

Как вы решаете, какое имя использовать?

Спасибо

Ответы [ 7 ]

30 голосов
/ 09 апреля 2016

Я получил исходный код .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
28 голосов
/ 21 апреля 2009

Вот мой свод правил

  • Если есть один параметр, я называю его T
  • Если имеется более одного параметра, я выбираю осмысленное имя и префикс с помощью T. Например, TKey, TValue

Для полуофициального мнения стоит взглянуть на руководящие принципы проектирования каркаса по этому вопросу:

7 голосов
/ 21 апреля 2009

В конце концов, это НЕ ДЕЙСТВИТЕЛЬНО имеет значение. Используйте соглашение об именах, которое имеет смысл.

public class MyDictionary<T1, T2>
{ }

, вероятно, не так полезен, как

public class MyDictionary<KeyType, ValueType>

(или TKey, TValue, если вы предпочитаете).

Если я смотрю на вашу реализацию и мне нужно подумать "хорошо, что это за штука" Т3 "? тогда ты не сделал хорошую работу.

2 голосов
/ 06 апреля 2010

Есть пара вещей, которые, я думаю, вы должны принять во внимание:

  1. Сколько существует аргументов типа?
  2. Есть ли на них ограничения ?
  3. Они использовали для чего-то конкретного?

В общем, я всегда добавляю к своим аргументам типа T и делаю их «достаточно описательными», то есть такими же описательными, какими они должны быть для меня, чтобы понять, что они делают и / или что от них требуется, когда я смотрю код через шесть месяцев.

Несколько примеров хорошего, по моему мнению, именования аргументов типа (нумерация в этом списке не зависит от нумерации выше ...):

  1. Один аргумент, и из имени класса (или из контекста в коде) очевидно, почему имя типа необходимо:

    List<T>
    

    Поскольку мы видим, что это список объектов типа T, и для T нет особых ограничений, нет необходимости давать более конкретное имя аргументу типа.

  2. Несколько аргументов, которые представляют разные вещи в универсальном классе / интерфейсе:

    IDictionary<TKey, TValue>
    

    Нам нужно уметь различать два аргумента, поэтому мы не предоставляем тип ключа для значения и наоборот. Таким образом, наименование аргументов Key и Value и добавление префикса к T представляется целесообразным.
    Я должен подчеркнуть, что это гораздо лучшая практика, чем, например, IDictionary<T1, T2> или IDictionary<T, U>, поскольку в последних двух случаях нет способа интуитивно узнать, какой аргумент будет использоваться для чего.

  3. Один аргумент типа, но тип должен удовлетворять тем или иным требованиям:

    Repository<TEntity> where TEntity : class, IEntity
    

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

1 голос
/ 21 апреля 2009

Пример от Microsoft:

public interface IDictionary<TKey, TValue>

Параметр type представляет что-то , поэтому, если вы хотите иметь читаемый код, это «что-то» должно быть очевидно из кода (без дополнительных комментариев). Использование имен типов, таких как T, V, U, не обязательно очевидно (но иногда это может быть).

0 голосов
/ 08 августа 2017

До сих пор я смотрел на все ответы и думаю, что все они частично правы, но не в полной мере рассматривают все ситуации.

Я считаю, что наименование должно всегда добавлять контекстуальное значение. Таким образом, именование параметра типа TEntity, потому что его тип IEntity будет неправильным, особенно если ограничение показывает его тип, и это показано в IntelliSense. Это было бы похоже на именование строковой переменной _string. В современном программировании мы просто этого не делаем. Имена переменных должны отражать их функциональную роль. Параметры типа не должны отличаться.

В случае одного параметра типа контекст обычно должен быть очевидным с точки зрения класса, поэтому T хорошо. Для параметров нескольких типов добавьте к каждому описательный контекст, например TKey и TValue. Это еще одна причина, по которой типы не должны использоваться - что, если оба параметра типа имеют одинаковый тип? TEntity1 и TEntity2?

Если существуют ограничения с именами типов, которые добавляют желаемый контекст, тогда допустимо использовать T, U и т. Д. Или T1, T2 и т. Д., Поскольку само ограничение отображает контекст , не говоря уже о IntelliSense.

Итак, мой ответ похож на ответы JaredPar и Tomas Lycken, но с дополнительной квалификацией и специально исключает третье правило Tomas Lycken, где вместо T следует использовать в случае параметров одного типа с ограничением (из-за класса контекст и IntelliSense).

0 голосов
/ 21 апреля 2009

Я не знаю каких-либо твердых соглашений для дженериков на самом деле.

Образцы, которые я видел, хотя и используют один из вариантов ff:

  • T для параметров одного типа
  • K для параметра второго типа, U для третьего параметра, например, SomeGeneric<T, K, U>
  • T и номер для параметра второго и третьего типа, например, SomeGeneric<T1, T2, T3>

Я думаю, что дженерики достаточно новы, чтобы общие отраслевые соглашения еще не были созданы.

...