Los estándares de codificación existentes en un gran proyecto de C # incluyen una regla de que todos los nombres de tipo deben estar completamente calificados, lo que prohíbe el empleo de la directiva 'usar'. Entonces, en lugar de lo familiar:
using System.Collections.Generic;
.... other stuff ....
List<string> myList = new List<string>();
(Probablemente no sea sorprendente que var
también esté prohibido).
Termino con:
System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();
Eso es un aumento del 134% en la escritura, sin que ninguno de esos aumentos proporcione información útil. En mi opinión, el 100% del aumento es ruido (desorden) que realmente impide la comprensión.
En más de 30 años de programación, he visto un estándar así propuesto una o dos veces, pero nunca implementado. La razón detrás de esto se me escapa. La persona que impone el estándar no es estúpida, y no creo que sea maliciosa. Lo que deja equivocada como la única otra alternativa a menos que me falte algo.
¿Alguna vez has oído hablar de que se impone un estándar de este tipo? Si es así, ¿cuál fue la razón detrás de esto? ¿Puedes pensar en otros argumentos que no sean "es estúpido" o "todos los demás emplean using
" que podrían convencer a esta persona de eliminar esta prohibición?
Razonamiento
Los motivos de esta prohibición fueron:
- Es engorroso pasar el mouse sobre el nombre para obtener el tipo completo. Es mejor tener siempre visible el tipo totalmente calificado todo el tiempo.
- Los fragmentos de código enviados por correo electrónico no tienen el nombre completo y, por lo tanto, pueden ser difíciles de entender.
- Al ver o editar el código fuera de Visual Studio (Notepad ++, por ejemplo), es imposible obtener el nombre de tipo completo.
Mi opinión es que los tres casos son raros, y que hacer que todos paguen el precio del código desordenado y menos comprensible solo para acomodar algunos casos raros es erróneo.
Los posibles problemas de conflicto de espacio de nombres, que esperaba que fueran la principal preocupación, ni siquiera se mencionaron. Eso es especialmente sorprendente porque tenemos un espacio de nombres MyCompany.MyProject.Core
, que es una idea especialmente mala. Hace mucho tiempo aprendí que nombrar cualquier cosa System
o Core
en C # es un camino rápido hacia la locura.
Como otros han señalado, los conflictos de espacio de nombres se manejan fácilmente mediante refactorización, alias de espacio de nombres o calificación parcial.
fuente
Respuestas:
La pregunta más amplia:
Sí, he oído hablar de esto, y el uso de nombres de objetos totalmente calificados evita las colisiones de nombres. Aunque es raro, cuando suceden, pueden ser excepcionalmente espinosos de entender.
Un ejemplo: ese tipo de escenario probablemente se explica mejor con un ejemplo.
Digamos que tenemos dos
Lists<T>
pertenecientes a dos proyectos separados.Cuando usamos el nombre del objeto totalmente calificado, queda claro cuál
List<T>
se está utilizando. Esa claridad obviamente tiene el costo de la verbosidad.Y podría estar discutiendo: "¡Espera! ¡Nadie usaría nunca dos listas como esa!" Que es donde señalaré el escenario de mantenimiento.
Usted es un módulo escrito
Foo
para su corporación que utiliza la corporación aprobada, optimizadaList<T>
.Más tarde, un nuevo desarrollador decide extender el trabajo que ha estado haciendo. Sin estar al tanto de los estándares de la compañía, actualizan el
using
bloque:Y puedes ver cómo las cosas van mal a toda prisa.
Debería ser trivial señalar que podría tener dos clases propietarias del mismo nombre pero en diferentes espacios de nombres dentro del mismo proyecto. Por lo tanto, no se trata solo de una colisión con las clases proporcionadas por .NET Framework.
La realidad:
ahora, ¿es probable que esto ocurra en la mayoría de los proyectos? No en realidad no. Pero cuando trabajas en un proyecto grande con muchas entradas, haces todo lo posible para minimizar las posibilidades de que las cosas exploten en ti.
Los grandes proyectos con múltiples equipos contribuyentes son un tipo especial de bestia en el mundo de las aplicaciones. Las reglas que parecen irrazonables para otros proyectos se vuelven más pertinentes debido a los flujos de entrada al proyecto y la probabilidad de que los contribuyentes no hayan leído las pautas del proyecto.
Esto también puede ocurrir cuando dos grandes proyectos se fusionan. Si ambos proyectos tenían clases con nombres similares, verá colisiones cuando comience a hacer referencia de un proyecto a otro. Y los proyectos pueden ser demasiado grandes para refactorizar o la gerencia no aprobará el gasto para financiar el tiempo dedicado a la refactorización.
Alternativas:
Si bien no preguntó, vale la pena señalar que esta no es una gran solución al problema. No es una buena idea crear clases que colisionen sin sus declaraciones de espacio de nombres.
List<T>
, en particular, debe tratarse como una palabra reservada y no como el nombre de sus clases.Del mismo modo, los espacios de nombres individuales dentro del proyecto deben esforzarse por tener nombres de clase únicos. Tener que tratar de recordar con qué espacio de nombres
Foo()
está trabajando es una sobrecarga mental que es mejor evitar. Dicho de otra manera: tenerMyCorp.Bar.Foo()
yMyCorp.Baz.Foo()
va a hacer tropezar a sus desarrolladores y es mejor evitarlos.Como mínimo, puede usar espacios de nombres parciales para resolver la ambigüedad. Por ejemplo, si no puede renombrar ninguna de las
Foo()
clases, puede usar sus espacios de nombres parciales:Razones específicas para su proyecto actual:
Actualizó su pregunta con los motivos específicos que recibió para su proyecto actual siguiendo ese estándar. Echemos un vistazo a ellos y realmente divaguemos por el sendero del conejito.
"¿Incómodo?" Mmm no. Molesto tal vez. Mover unas onzas de plástico para cambiar el puntero en pantalla no es engorroso . Pero yo divago.
Esta línea de razonamiento parece más un encubrimiento que otra cosa. Por supuesto, supongo que las clases dentro de la aplicación tienen un nombre débil y debe confiar en el espacio de nombres para obtener la cantidad adecuada de información semántica que rodea el nombre de la clase.
Esta no es una justificación válida para nombres de clase totalmente calificados, quizás sea una justificación válida para usar nombres de clase parcialmente calificados.
Esta línea de razonamiento (¿continua?) Refuerza mi sospecha de que las clases actualmente están mal nombradas. Nuevamente, tener nombres de clase pobres no es una buena justificación para requerir que todo use un nombre de clase completamente calificado. Si el nombre de la clase es difícil de entender, hay mucho más mal que lo que pueden arreglar los nombres de clase completamente calificados.
De todas las razones, esta casi me hizo escupir mi bebida. Pero de nuevo, me estoy desviando.
Me pregunto por qué el equipo edita o visualiza código con frecuencia fuera de Visual Studio. Y ahora estamos viendo una justificación que es bastante ortogonal a lo que los espacios de nombres deben proporcionar. Este es un argumento respaldado por herramientas, mientras que los espacios de nombres están ahí para proporcionar una estructura organizativa al código.
Parece que el proyecto propio sufre de convenciones de nomenclatura deficientes junto con desarrolladores que no están aprovechando lo que las herramientas pueden proporcionarles. Y en lugar de resolver esos problemas reales, han intentado aplicar una tirita sobre uno de los síntomas y requieren nombres de clase completamente calificados. Creo que es seguro clasificar esto como un enfoque equivocado.
Dado que hay clases mal nombradas, y suponiendo que no pueda refactorizar, la respuesta correcta es usar el IDE de Visual Studio para su máximo beneficio. Posiblemente considere agregar un complemento como el paquete VS PowerTools. Luego, cuando estoy mirando
AtrociouslyNamedClass()
, puedo hacer clic en el nombre de la clase, presionar F12 y ser llevado directamente a la definición de la clase para comprender mejor lo que está tratando de hacer. Del mismo modo, puedo hacer clic en Shift-F12 para encontrar todos los puntos en el código que actualmente tienen que usarAtrociouslyNamedClass()
.Con respecto a las preocupaciones de herramientas externas, lo mejor que puede hacer es simplemente detenerlo. No envíe fragmentos de correo electrónico de un lado a otro si no están claros de inmediato a qué se refieren. No use otras herramientas fuera de Visual Studio, ya que esas herramientas no tienen la inteligencia que rodea el código que su equipo necesita. Notepad ++ es una herramienta increíble, pero no está hecha para esta tarea.
Así que estoy de acuerdo con su evaluación con respecto a las tres justificaciones específicas que se le presentaron. Dicho esto, lo que creo que le dijeron fue "Tenemos problemas subyacentes en este proyecto que no pueden / no abordarán y así es como los" solucionamos ". Y eso obviamente habla de problemas más profundos dentro del equipo que pueden servir como señales de alerta para usted.
fuente
usings
pero no parece que su proyecto califique como uno de esos casos.Trabajé en una compañía donde tenían muchas clases con el mismo nombre, pero en diferentes bibliotecas de clases.
Por ejemplo,
Podría decirse que es un mal diseño, pero sabe cómo se desarrollan orgánicamente estas cosas y cuál es la alternativa: cambiar el nombre de todas las clases para incluir el espacio de nombres. ¿Refactorización importante de todo?
En cualquier caso, había varios lugares donde los proyectos que hacían referencia a todas estas bibliotecas diferentes necesitaban usar múltiples versiones de la clase.
Con el
using
directamente en la parte superior, esto fue un gran dolor en el culo, ReSharper haría cosas extrañas para intentar que funcionara, reescribiendo lasusing
directivas sobre la marcha, obtendría el Cliente no puede ser lanzado como ... Errores de estilo del cliente y no saber qué tipo era el correcto.Entonces, teniendo al menos el espacio de nombres parcial,
o
mejoró enormemente la legibilidad del código y lo hizo explícito qué objeto deseaba.
No era un estándar de codificación, no era el espacio de nombres completo, y no se aplicaba a todas las clases como estándar.
fuente
No es bueno ser demasiado detallado o demasiado corto: uno debe encontrar un medio dorado para ser lo suficientemente detallado como para evitar errores sutiles, evitando al mismo tiempo escribir demasiado código.
En C #, un ejemplo de eso son los nombres de los argumentos. Encontré varias veces un problema en el que pasé horas buscando una solución, mientras que un estilo de escritura más detallado podría evitar el error en primer lugar. El problema consiste en un error en el orden de los argumentos. Por ejemplo, ¿te parece bien?
A primera vista, se ve perfectamente bien, pero hay un error. Las firmas de los constructores de las excepciones son:
¿Notó el orden de los argumentos?
Al adoptar un estilo más detallado donde se especifica el nombre de un argumento cada vez que el método acepta dos o más argumentos del mismo tipo , evitamos que el error vuelva a ocurrir, y así:
obviamente es más largo de escribir, pero resulta en menos tiempo de depuración desperdiciado.
Empujado a los extremos, uno podría forzar el uso de argumentos con nombre en todas partes , incluso en métodos como
doSomething(int, string)
donde no hay forma de mezclar el orden de los parámetros. Esto probablemente dañará el proyecto a largo plazo, resultando en mucho más código sin el beneficio de prevenir el error que describí anteriormente.En su caso, la motivación detrás del “No
using
regla” es que debe hacer que sea más difícil de usar el tipo incorrecto, como por ejemploMyCompany.Something.List<T>
vsSystem.Collections.Generic.List<T>
.Personalmente, evitaría esa regla porque, en mi humilde opinión, el costo del código difícil de leer está muy por encima del beneficio de un riesgo ligeramente reducido de mal uso del tipo incorrecto, pero al menos, hay una razón válida para esta regla.
fuente
paramName
con elInvokerParameterName
atributo y emite una advertencia si no existe dicho parámetro.SomeBusiness.Something.DoStuff(string name, string description)
? Ninguna herramienta es lo suficientemente inteligente como para comprender qué es un nombre y qué es una descripción.Los espacios de nombres le dan al código una estructura jerárquica, permitiendo nombres más cortos.
Si permite la palabra clave "usar", hay una cadena de eventos ...
(porque incluyen todos los espacios de nombres que puedan desear)
Entonces, para evitar el riesgo, todos comienzan a usar nombres realmente largos:
La situación se intensifica ...
He visto que esto sucede, así que puedo simpatizar con las compañías que prohíben el "uso".
fuente
using
es la opción nuclear. Los alias de espacio de nombres y la calificación parcial son preferibles.El problema con
using
es que mágicamente se agrega al espacio de nombres sin una declaración explícita. Esto es un problema mucho mayor para el programador de mantenimiento que encuentra algo comoList<>
y sin estar familiarizado con el dominio, no sabe quéusing
cláusula lo ha introducido.Un problema similar ocurre en Java si uno escribe en
import Java.util.*;
lugar de,import Java.util.List;
por ejemplo; la última declaración documenta qué nombre se ha introducido para que cuandoList<>
ocurra más tarde en la fuente, su origen se conozca a partir de laimport
declaración.fuente