Ich stimme @MartinMaat hinsichtlich der Auswahl Ihrer Schlachten zu.
Es gibt viele Fälle von "nur für den Fall", weil die Sprache nicht wirklich verstanden wird, obwohl die Sprache in ihren Regeln für viele dieser Dinge festgelegt ist - über die Klammerung eines Ausdrucks, der sie nicht benötigt, weil die Vorrangregeln von nicht verstanden werden die Sprache. Dennoch ist eine solche Praxis meist harmlos.
Als ich jünger war, hatte ich das Gefühl, wir sollten die Details der Sprache lernen und so vermeiden, solch überflüssigen Code zu schreiben. (Einer meiner Lieblingstiere war return (0);
mit seinen unnötigen Parens.) Allerdings moderiere ich diese Position jetzt, insbesondere weil wir jetzt so viele verschiedene Sprachen verwenden, von Client zu Server springen usw. Also habe ich jetzt einige geschnitten locker für einige solche Probleme.
Sie sind der Meinung, dass zyklomatische Starts zu logisch begründeten Argumenten führen. Schauen wir uns Code Coverage und vor allem eine höhere Reichweite :
- Jede Entscheidung trifft jedes mögliche Ergebnis
Da wir die neue Operation nicht zwingen können, NULL zurückzugeben, gibt es keine Möglichkeit, für diese bedingte Operation eine höhere Codeabdeckung zu erreichen. Natürlich kann dies für Ihre Organisation wichtig sein oder auch nicht!
Aufgrund dieses Problems mit der Codeabdeckung würde ich es jedoch höher priorisieren als über Klammern.
Auf der anderen Seite wird der zugrunde liegende generierte Code wahrscheinlich kein Bit darunter leiden, da die Codegenerationen, JIT und Optimierer alle verstehen, dass ein new
ed-Wert niemals null sein wird. Die tatsächlichen Kosten entstehen also nur in Bezug auf Lesbarkeit und Quellcode-Abdeckung.
Ich würde Sie fragen, wie der "else-Teil" einer solchen if-Anweisung aussieht.
Wenn es keinen anderen Teil gibt, würde ich argumentieren, dass es potenziell gefährlich ist , einfach vom Ende der Routine abzufallen oder zu einem anderen Code durchzufallen (dh nein else
dazu if
), da dies "nur für den Fall" logischerweise darauf hindeutet, dass Anrufer und / oder oder weiterer Code in der Zeile behandelt auch NULL.
Wenn es lautet:
p = new Object ();
if ( p != null ) {
p.field = value;
}
else {
throw new NullReferenceException ();
}
dann ist das wirklich übertrieben, da die Sprache das alles für uns erledigt.
Ich könnte vorschlagen, den Sinn der Bedingung umzukehren - vielleicht fühlt sich Ihr Kollege damit wohler:
p = new Object ();
if ( p == null ) {
throw new NullReferenceException ();
}
else {
p.field = value;
}
Jetzt können Sie sich für die Entfernung des else-Wrappers aussprechen, da dies eindeutig nicht erforderlich ist:
p = new Object ();
if ( p == null ) {
throw new NullReferenceException ();
}
p.field = value;
Damit ist nun "nur für den Fall" bedingt, während der nachfolgende Code dies nicht ist. Dieser Ansatz verstärkt weiter, dass bei fehlgeschlagener Zuweisung die entsprechende Antwort ausgelöst wird, anstatt weiterhin Code in dieser Methode und / oder in dieser Aufrufkette auszuführen (ohne eine andere ordnungsgemäße Behandlung des Zuordnungsfehlers).
Zusammenfassend gibt es hier also zwei logisch begründete Argumente gegen diese Praxis:
- Höhere Codeabdeckungsgrade können nicht erreicht werden, da wir nicht aus dem Speicher (oder einem Konstruktorfehler) zwingen können, null zurückzugeben.
- Das "nur für den Fall" (wie oben in der Frage gezeigt) ist unvollständig und als solches fehlerhaft, da die Erwartungen inkonsistent sind, wie null von anderem Code jenseits / nach dem behandelt werden soll
p.field = value;
.
Grundsätzlich scheint es, als ob Ihr Kollege vielleicht auf dem Zaun steht, Ausnahmen zu verwenden - obwohl es hier in C # keine Wahl für solche Dinge gibt. ( Wenn wir gut getesteten Code wünschen, können wir nicht sowohl für ein Ausnahmemodell für die Behandlung von Null als auch für ein Nicht-Ausnahmemodell mit Null-Rückgabewerten nebeneinander codieren.) Vielleicht, wenn Sie mit Ihrem Kollegen über diese Themen nachdenken, Sie werden etwas Licht sehen!