Decidí hacer esta pregunta aquí en lugar del desbordamiento de la pila porque es bastante subjetivo.
En C #, típicamente veo tipos genéricos con nombres muy pobres. Específicamente, "T" se usa comúnmente, pero no es un nombre significativo en sí mismo. Por ejemplo:
class Fruit<T>
{
T fruit;
}
Si bien este es el enfoque típico, ¿alguien recomendaría no hacerlo? Y si es así, ¿cuál sería una convención de nomenclatura razonable para tipos genéricos en el contexto de C # para funciones y clases genéricas?
En mi ejemplo anterior, supongamos que el tipo genérico T
siempre debe ser un tipo de fruta, como Apple
o Orange
. El tipo T
debe hacer obvio que es un tipo de fruta, por lo que quizás sea un nombre mejor FruitType
, por lo que terminamos con:
class Fruit<FruitType>
{
FruitType fruit;
}
Esto es solo para darles una idea de lo que estoy buscando. ¿Qué es una "regla de oro" aceptable para este problema?
Respuestas:
De hecho es subjetivo ... ish .
Como algunas personas encuentran que
i
es perfectamente válido para una variable de bucle for, algunos piensan queT
es perfectamente válido para un marcador de posición de tipo en una clase genérica.Personalmente, defiendo este enfoque, es una convención común y la gente generalmente sabe a qué te refieres.
Cuando el tipo es significativo, usaría un nombre significativo, pero generalmente lo comienzo con T. Recientemente desarrollé una clase de diccionario genérico (no pregunte) y la declaración fue
Sin embargo, para algo como una Tupla, donde los tipos son esencialmente sin sentido, considero que lo siguiente es perfectamente aceptable.
fuente
i
yT
trabajo, y esto es medible en principio (es decir, es medible si la comprensión del código fuente aumenta si, por ejemplo, los índices de bucle obtienen identificadores diferentes). El hecho de que sea difícil de medir no significa que tengamos que etiquetar la etiqueta "subjetiva" en todo. Dado el amplio uso sin problemas obvios, es bastante razonable decir incluso sin medir que esto realmente funciona.i
yT
son malvados . Uno nunca debe usar nombres de una sola letra", escriba la respuesta. He agregado un ish para ayudar a satisfacer a todos :)T
tiene sentido cuando hablamos de un tipo sin restricciones,TFruit
tiene sentido porque me dice "Cualquier tipo con la restricción de que es una fruta". Esto parece una buena "regla general" para nombrar parámetros de tipo genérico. ¡¡Gracias!!Creo que tienes razón, aunque T se ha convertido en un estándar. Probablemente se origina en los viejos tiempos de C ++ y la redacción "de tipo T". Considero que es una buena práctica ser lo más descriptivo posible, pero eso es subjetivo.
Puede elegir T como prefijo, al igual que muchas personas eligen I para las interfaces. Así
Sería un buen nombre en mi humilde opinión. Prefiero los prefijos a los sufijos en la mayoría de los casos, ya que está claro de inmediato lo que estás viendo cuando te topas con él y es más fácil buscar con cosas como Intellisense. También es una buena práctica para UI-Controls, cuando lo más probable es que siempre sepas el tipo (por ejemplo, TextBox) pero no estés 100% seguro del nombre descriptivo que le diste.
El lado negativo es que se ve mal cuando el tipo en sí comienza con T. Por lo tanto, creo que sería bueno sufijar el tipo genérico en casos especiales, como el siguiente.
Tenga en cuenta que esta es solo mi opinión y altamente subjetiva. Pero creo que tengo un punto menor al preferir el prefijo al sufijo.
fuente
T
prefijo para los parámetros de tipo yI
para los nombres de interfaz se requiere explícitamente ( reglas " DO ...") en las Pautas de diseño del marco.TFruit
aquí trae a la mesaT
. Usar nombres comoTType
oTypeT
es ciertamente una tontería. No agrega información alguna sobre soloT
. Se transmite exactamente la misma información.Microsoft tiene una directriz oficial con respecto a los genéricos: nombres de clases, estructuras e interfaces (citado aquí y en forma de libro: Pautas de diseño de marcos ).
En cuanto a su pregunta específica, dice:
fuente
El objetivo de los genéricos es delegar la funcionalidad: la clase genérica hace una cosa, su argumento hace otra. El ejemplo del libro de texto es una colección genérica: la colección almacena 'cosas', pero no le importa cuáles son estas cosas. Un nombre genérico (sic!), Por lo tanto, tiene una cierta lógica: no queremos que sea descriptivo, porque no hay nada que describir más que "es el argumento de tipo genérico", que el nombre
T
abarca exhaustivamente (considerando la Convención). Ser descriptivo es bueno, pero ser demasiado descriptivo sugiere restricciones que no existen.A veces, sin embargo, una clase o método genérico tiene más de un parámetro de tipo, y en este punto, tiene sentido darles nombres más descriptivos, de modo que su rol se vuelva obvio. Un buen ejemplo sería para un tipo de colección de clave-valor, donde clave y valor son genéricos; llamarlos
T
yS
(oQ
lo que sea) sería menos útil que llamarlos, digamos,KeyType
yValueType
, oTKey
yTVal
.fuente
La respuesta es de hecho subjetiva. Sin embargo, tiene mérito como pregunta, ya que el código debe autodocumentarse, y posiblemente todos podamos aprender algunas formas mejores de hacerlo.
Las siguientes son las convenciones que aprendí y sigo:
Los parámetros de tipo genérico nunca deberían confundirse con clases concretas. Esto generalmente fomenta un prefacio
T
independientemente de lo que sigue, al igual que las interfaces generalmente están precedidasI
.Un único parámetro de tipo genérico en una clase o método generalmente debe etiquetarse
T
. Esta es una convención casi universalmente entendida que se remonta a las plantillas de C ++.Múltiples parámetros de tipo genérico en la misma declaración de clase o método deben comenzar con T, pero deben diferenciarse por algún medio conciso pero comprensible.
TIn
yTOut
, por ejemplo, son GTP comunes y bien entendidos para un método que acepta una entrada genérica fuertemente tipada y produce una salida genérica fuertemente tipada.Múltiples tipos diferenciados pero no notables, como para una clase que contiene como .Net's Tuple o tipos de delegado como Func, Predicate y Action, pueden etiquetarse como T1, T2, T3, etc. Sin embargo, las declaraciones GTP "notables" (que tienen un propósito definido y / o restricciones de tipo muy específicas) debería tener algo más descriptivo.
Un único tipo genérico en un método, que difiere del tipo genérico de una clase que lo contiene, puede seguir la regla anterior con respecto a varios tipos en una clase o método, O si el tipo no es notable, aparte de ser diferente, se le puede dar una diferente sola letra, a menudo
U
oV
. Esto es nuevamente una convención que se remonta a las plantillas de C ++.Lo que elija hacer, manténgalo constante; no etiquete un GTP para una clase
T
, y la siguienteTParam
, a menos que la segunda clase esté anidada en la primera yT
no esté disponible para su uso en la segunda.fuente