variable practices for codigo classes best c# .net generics naming-conventions
http://referencesource.microsoft.com/dotnet46.zip

practices - class naming conventions c#



¿Cuáles son las pautas de denominación de parámetros de tipo? (7)

Al final, no importa REALMENTE Utilice una convención de nomenclatura que tenga sentido.

public class MyDictionary<T1, T2> { }

Probablemente no sea tan útil como

public class MyDictionary<KeyType, ValueType>

(o TKey, TValue, si lo prefiere).

Si estoy viendo tu implementación y tengo que pensar "ok, ¿qué es esta cosa ''T3'' otra vez?" entonces no hiciste un buen trabajo

Noté, como lo vi en el libro Essential C # 3.0 , que los parámetros generalmente se definen como T o TEntity

Por ejemplo:

public class Stack<T> { }

o

public class EntityCollection<TEntity> { }

¿Cómo decides qué nombre usar?

Gracias


Aquí está mi conjunto de reglas

  • Si hay un parámetro, lo llamo T
  • Si hay más de un parámetro, escojo un nombre significativo y un prefijo con T. Por ejemplo, TKey, TValue

Para una opinión semioficial, vale la pena mirar las pautas de diseño del marco sobre el tema:


Busqué el código fuente de .NET Framework 4.6 en http://referencesource.microsoft.com/dotnet46.zip . Lo extrajo y procesó los datos para extraer el nombre del parámetro genérico de todas las declaraciones de clase genéricas.

Nota: solo extraje el nombre del parámetro genérico de las clases genéricas con un solo parámetro genérico. Por lo tanto, esto no tiene en cuenta las clases genéricas con múltiples parámetros genéricos.

grep -nohrP "class /w+<T/w*>" | sed -e ''s/.*/<//'' -e ''s/>//'' | sort | uniq -cd | sort -bgr

Resultado:

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


Ejemplo de Microsoft:

public interface IDictionary<TKey, TValue>

El parámetro de tipo representa algo , por lo que si desea tener un código legible, este "algo" debería ser obvio en el código (sin comentarios adicionales). El uso de nombres de tipo como T, V, U no es necesariamente obvio (pero a veces puede serlo).


Hay un par de cosas que creo que deberías tener en cuenta:

  1. ¿Cuántos argumentos de tipo hay?
  2. ¿Hay alguna restricción en ellos?
  3. ¿Se usan para algo en particular?

En general, siempre prefijo mis argumentos de tipo con T , y los hago "suficientemente descriptivos", es decir, tan descriptivos como deben ser para que yo comprenda lo que hacen y / o lo que se requiere de ellos, cuando veo el Código en seis meses.

Un par de ejemplos de, en mi opinión, una buena denominación de los argumentos de tipo (la numeración en esta lista es independiente de la numeración anterior ...):

  1. Un argumento, y es obvio por el nombre de la clase (o por el contexto en el código) por qué se necesita el nombre del tipo:

    List<T>

    Como podemos ver que esta es una lista de objetos de tipo T , y no hay restricciones específicas en T , no es necesario dar un nombre más específico al argumento de tipo.

  2. Varios argumentos, que representan cosas diferentes en la clase / interfaz genérica:

    IDictionary<TKey, TValue>

    Necesitamos poder distinguir entre los dos argumentos, por lo que no suministramos el tipo de clave para el valor y viceversa. Por lo tanto, nombrar los argumentos Key y Value , y prefijar con T , parece apropiado.
    Debo enfatizar que esta es una práctica mucho mejor que, por ejemplo, IDictionary<T1, T2> o IDictionary<T, U> , ya que en los dos últimos casos no hay manera de saber intuitivamente qué argumento se usará para qué.

  3. Un tipo de argumento, pero el tipo debe cumplir algunos requisitos u otros:

    Repository<TEntity> where TEntity : class, IEntity

    Ya que requerimos que el tipo implemente otra interfaz, tiene sentido darle un aviso al programador de que este es el caso. Elija algún nombre informativo que le ayude a ver qué se requiere del tipo, y prefiértelo con T


He visto todas las respuestas hasta ahora, y creo que todas son parcialmente correctas, pero no consideramos completamente todas las situaciones.

Mi opinión es que la denominación siempre debe agregar valor contextual. Por lo tanto, nombrar un parámetro de tipo TEntity porque su tipo es IEntity sería incorrecto, especialmente porque la restricción muestra su tipo y esto se muestra en IntelliSense. Sería como nombrar una cadena de cadena _string . En la programación moderna, simplemente no lo hacemos. Los nombres de las variables deben reflejar su papel funcional. Los parámetros de tipo no deben ser diferentes.

En el caso de un parámetro de tipo, el contexto normalmente debería ser obvio en términos de la clase, por lo que T está bien. Para los parámetros de tipo múltiple, agregue un contexto descriptivo a cada uno, como TKey y TValue . Esta es otra razón por la que no se deben usar los tipos. ¿Qué sucede si ambos parámetros de tipo son del mismo tipo? TEntity1 y TEntity2 ?

Si hay restricciones con nombres de tipo que agregan el contexto deseado, entonces es aceptable usar T , U , etc. o T1 , T2 , etc. porque la restricción en sí misma muestra el contexto, por no mencionar IntelliSense.

Por lo tanto, mi respuesta es similar a las respuestas de JaredPar y Tomas Lycken, pero con calificación adicional, y excluye específicamente la tercera regla de Tomas Lycken donde, en cambio, T debería usarse en el caso de parámetros de tipo único con una restricción (debido al contexto de clase e IntelliSense).


No tengo conocimiento de ninguna convención sólida para los genéricos realmente.

Las muestras que he visto utilizan una de las siguientes variaciones:

  • T para parámetros de tipo único
  • K para un segundo parámetro de tipo, U para un tercero, por ejemplo, SomeGeneric<T, K, U>
  • T y un número para un segundo y tercer parámetro de tipo, por ejemplo, SomeGeneric<T1, T2, T3>

Supongo que los genéricos son lo suficientemente nuevos como para que aún no se hayan establecido convenciones comunes de la industria.