Pesquisa de site

c# - Existe uma convenção de nomenclatura para o parâmetro de tipo em código genérico (estilo bracy)


Existe uma convenção de nomenclatura para parâmetros de tipo em código com tipos genéricos?

Estou fazendo um pouco de TypeScript agora, mas ele tem o mesmo estilo de parametrização de tipo que C#, Java, AS3 etc.

Vejo o T mais utilizado, também em:

interface Container<T> {
    getContent(): List<T>;
}

Mas e se você precisar de mais de 1 tipo? Eu vejo letras únicas, geralmente T, U e V. Às vezes K e V são usados para a chave e valor de mapeamentos.

Certamente deve haver uma melhor prática para isso?

Resposta #1

Um padrão amplamente adotado é T1, T2, T3, etc., se houver mais de 1 parâmetro de tipo genérico sem propósito definido (ou seja, quando a finalidade prevista dos parâmetros não é conhecida dentro da própria classe, então você realmente não consegue dar a eles um nome mais descritivo).

Veja a classe Tuple, como um bom exemplo aqui.

Tuple possui as seguintes formas:

Tuple<T1>
Tuple<T1, T2>
Tuple<T1, T2, T3>
Tuple<T1, T2, T3, T4>
Tuple<T1, T2, T3, T4, T5>
Tuple<T1, T2, T3, T4, T5, T6>
Tuple<T1, T2, T3, T4, T5, T6, T7>

Usar qualquer outra coisa em casos como este provavelmente será confuso para qualquer pessoa que estiver lendo seu código. Ao ver T1, T2, T3, todos saberão que são parâmetros de tipo genérico.

No entanto, no caso de parâmetros genéricos com propósitos predefinidos, nomes específicos são mais apropriados. Como apontado por @AlexeiLevenkov, para valores de retorno também é bastante comum usar TResult para diferenciá-lo de quaisquer outros argumentos de tipo. Func fornece um bom exemplo disso, como descrito na documentação aqui, com o exemplo abaixo:

public delegate TResult Func<in T, out TResult>(
    T arg
)

De forma semelhante, Dictionary usa <TKey, TValue> como seus parâmetros de tipo. Isso porque é necessário ficar imediatamente claro qual é qual. O código da classe não sabe o que TKey ou TValue são, mas sabe que eles representam chaves e valores, então faz sentido colocar essa informação no nome do parâmetro.

A Microsoft tem algumas diretrizes de nomenclatura (antigas!) aqui, onde eles cobrem outro caso interessante. Eles sugerem indicar restrições aplicadas a um parâmetro de tipo no próprio nome do parâmetro, como segue:

public interface ISessionChannel<TSession> where TSession : ISession
{
    TSession Session { get; }
}

Neste caso, como o parâmetro genérico é restrito a ser um ISession, faz sentido comunicar isso nomeando o parâmetro como TSession.

Artigos relacionados