Estoy de acuerdo con @MartinMaat sobre elegir tus batallas.
Hay muchos casos de "por si acaso" debido a que realmente no comprende el idioma a pesar de que el lenguaje se fija en sus reglas para muchas de estas cosas, sobre paréntesis de una expresión que no lo necesita debido a que no comprende las reglas de precedencia de el idioma. Pero aún así, tal práctica es mayormente inofensiva.
Cuando era más joven, sentí que deberíamos aprender los detalles del idioma y así evitar escribir un código tan superfluo. (Una de mis manías era return (0);
con sus parentes innecesarios). Sin embargo, ahora modero esa posición, en particular, porque ahora usamos tantos idiomas diferentes, saltando de cliente a servidor, etc. Así que ahora corté algunos flojo para algunos de esos problemas.
Su punto sobre ciclomático comienza a ir a un argumento lógicamente razonado. Echemos un vistazo a la cobertura de código y especialmente a los niveles más altos de cobertura :
- Cada decisión toma todos los resultados posibles
Como no podemos obligar a la nueva operación a devolver NULL, no hay forma de alcanzar niveles más altos de cobertura de código para esta operación condicional. ¡Por supuesto, esto puede o no ser importante para su organización!
Sin embargo, debido a este problema de cobertura del código, lo priorizaría más que al paréntesis excesivo.
Por otro lado, el código generado subyacente probablemente no sufrirá un poco por esto ya que las generaciones de código, JIT y optimizadores entienden que un new
valor ed nunca será nulo. Por lo tanto, el costo real solo viene en términos de legibilidad y capacidades de cobertura del código fuente.
Le preguntaría cómo es la "parte-otra" de tal declaración if.
Si no hay otra parte, diría que simplemente caerse del final de la rutina o caer a otro código (es decir, no else
para esto if
) es potencialmente peligroso, ya que ahora "por si acaso" sugiere lógicamente que las personas que llaman y / o código adicional en la línea maneja NULL también.
Si se lee:
p = new Object ();
if ( p != null ) {
p.field = value;
}
else {
throw new NullReferenceException ();
}
entonces esto es realmente excesivo, ya que el lenguaje hace todo eso por nosotros.
Podría sugerir invertir el sentido de lo condicional, tal vez su colega se sienta más cómodo con esto:
p = new Object ();
if ( p == null ) {
throw new NullReferenceException ();
}
else {
p.field = value;
}
Ahora puede abogar por la eliminación del envoltorio else, ya que es claramente innecesario:
p = new Object ();
if ( p == null ) {
throw new NullReferenceException ();
}
p.field = value;
Con esto, el "por si acaso" es ahora lo que es condicional, mientras que el código siguiente no lo es. Este enfoque refuerza aún más que cuando la asignación falla, se arroja la respuesta adecuada, en lugar de continuar ejecutando código en este método y / o en esta cadena de llamadas (sin ningún otro manejo adecuado del error de asignación).
Entonces, en resumen, hay dos argumentos lógicamente razonados para hacer aquí en contra de esta práctica:
- No se pueden alcanzar niveles de cobertura de código más altos ya que no podemos forzar la falta de memoria (o cualquier falla del constructor) para devolver nulo.
- El "por si acaso" (como se muestra arriba en la pregunta) está incompleto y, como tal, es defectuoso debido a la inconsistencia en las expectativas de cuán nulo sería manejado por otro código más allá del pasado
p.field = value;
.
Básicamente, parece que tal vez su colega está cerca de usar excepciones, a pesar de que aquí en C # no hay otra opción para tales cosas. ( Si queremos un código bien probado, no podemos codificar tanto un modelo de excepción para manejar un modelo nulo como uno que no sea de excepción usando valores de retorno nulo, uno al lado del otro). Quizás si razona con su colega a través de estos temas, ¡Verán algo de luz!