Also gab mein Professor Feedback zu einem Projekt, an dem ich gearbeitet habe. Er hat ein paar Zeichen für diesen Code angedockt:
if (comboVendor.SelectedIndex == 0) {
createVendor cv = new createVendor();
cv.ShowDialog();
loadVendors();
}
Dies ist in einem Combobox "Index geändert" -Handler. Es wird verwendet, wenn der Benutzer einen neuen Lieferanten erstellen möchte. Die Option "Mein Top" (Index 0, der sich nie ändert) öffnet den Dialog "Neuen Lieferanten erstellen". Der Inhalt meines Kombinationsfelds sieht also so aus:
Create New Vendor...
Existing Vendor
Existing Vendor 2
Existing Vendor 3
Sein Problem ist mit dem ersten Zeilencode:
if (comboVendor.SelectedIndex == 0)
Er behauptet, dass die 0 eine Konstante sein sollte, und hat mich deswegen angedockt. Er behauptet, ich sollte überhaupt keine Literale in meinem Code verwenden.
Die Sache ist, ich verstehe nicht, warum ich diesen Code in dieser Situation zu einer Konstanten machen möchte. Dieser Index wird sich niemals ändern, und Sie müssen ihn auch nicht anpassen. Es scheint wie eine Verschwendung von Speicher, eine einzelne 0 im Speicher zu belassen, die für eine bestimmte Situation verwendet wird und sich nie ändert.
-1
instr.indexOf(substr) != -1
für "str
enthältsubstr
" vollkommen gerechtfertigt sind. Aber hier ist die Bedeutung der 0 weder offensichtlich (in welchem Verhältnis steht sie zum Erstellen eines neuen Anbieters?) Noch wirklich konstant (was ist, wenn sich der Weg zum Erstellen eines neuen Anbieters ändert?).int.Zero
stattdessen verwenden, um ihn glücklich zu machen :)Antworten:
Die eigentliche korrekte Vorgehensweise in C # besteht darin, sich überhaupt nicht auf die Reihenfolge der ComboItems zu verlassen .
quelle
Die Reihenfolge im Kombinationsfeld kann sich ändern. Was ist, wenn Sie eine andere Option wie "Speziellen Anbieter erstellen ..." vor "Neuen Anbieter erstellen ..." hinzufügen?
Die Verwendung einer Konstante hat den Vorteil, dass Sie nur dann die Konstante und nicht alle Methoden ändern müssen, wenn es viele Methoden gibt, die von der Reihenfolge des Kombinationsfelds abhängen.
Die Verwendung einer Konstante ist auch lesbarer als ein Literal.
Die meisten kompilierten Sprachen ersetzen die Konstante zur Kompilierungszeit, sodass keine Leistungseinbußen auftreten.
quelle
Diese Situation, die Sie beschreiben, ist ein Urteil, persönlich würde ich keine verwenden, wenn sie nur einmal verwendet wird und bereits lesbar ist.
Die wirkliche Antwort ist jedoch, dass er dies ausgewählt hat, um Ihnen eine Lektion zu erteilen.
Vergessen Sie nicht, dass er Professor ist. Seine Aufgabe ist es, Ihnen Codierung und Best Practices beizubringen.
Ich würde sagen, er macht einen ziemlich guten Job.
Sicher, dass er ein bisschen absolut abschneidet, aber ich bin sicher, dass Sie es sich noch einmal überlegen werden, bevor Sie magische Zahlen verwenden.
Außerdem ist er Ihnen so nahe gekommen, dass Sie sich einer Online-Community über Programmierer anschließen können, um herauszufinden, was in dieser Situation als Best Practice gilt.
Hut ab vor deinem Professor.
quelle
Die Tatsache, dass Sie das erklären mussten, beweist, warum Sie eine Konstante verwenden sollten. Wenn Sie eine Konstante wie eingeführt hätten
NEW_VENDOR_DIALOG
, wäre Ihr Code selbsterklärender. Außerdem optimieren Compiler Konstanten, damit sich die Leistung nicht ändert.Schreiben Sie Programme für Programmierer, nicht für Compiler. Es sei denn, Sie versuchen speziell, eine Mikrooptimierung durchzuführen, wie es nicht scheint.
quelle
Ich würde zustimmen. Die Verwendung von Null ist hier "Magie". Stellen Sie sich vor, Sie lesen diesen Code zum ersten Mal. Sie wissen nicht, warum Null etwas Besonderes ist, und das Literal sagt nichts darüber aus, warum Null etwas Besonderes ist. Wenn Sie stattdessen sagten
if(comboVendor.SelectedIndex == CreateNewVendorIndex)
, wird dem erstmaligen Leser sehr deutlich, was der Code bedeutet.Das ist eine extreme Position. Eine realistische Position wäre zu sagen, dass die Verwendung von Literalen eine rote Fahne ist, die anzeigt, dass der Code möglicherweise nicht so klar ist, wie er sein könnte. Manchmal ist es angebracht.
Dass es sich nie ändern wird, ist ein hervorragender Grund, es zu einer Konstante zu machen . Deshalb werden Konstanten Konstanten genannt. weil sie sich nie ändern.
"Ja wirklich?" Sie können keine Situation sehen, in der jemand die Reihenfolge der Dinge in einem Kombinationsfeld ändern möchte?
Die Tatsache, dass Sie einen Grund sehen, warum sich dies in Zukunft ändern könnte, ist ein guter Grund, es nicht zu einer Konstanten zu machen. Es sollte sich vielmehr um ein nicht konstantes, schreibgeschütztes statisches Ganzzahlfeld handeln. Eine Konstante sollte eine Menge sein, die garantiert für alle Zeiten gleich bleibt . Pi und die Ordnungszahl von Gold sind gute Konstanten. Versionsnummern sind nicht; Sie ändern jede Version. Der Goldpreis ist offensichtlich eine schreckliche Konstante; es ändert sich jede Sekunde. Machen Sie nur konstante Dinge, die sich niemals ändern .
Jetzt kommen wir zum Kern der Sache.
Dies ist vielleicht die wichtigste Zeile in Ihrer Frage, da sie darauf hinweist, dass Sie ein tiefes Verständnis von (1) Gedächtnis und (2) Optimierung haben. Du bist in der Schule, um zu lernen, und jetzt wäre ein guter Zeitpunkt, um ein korrektes Verständnis der Grundlagen zu erlangen. Können Sie im Detail erklären, warum Sie glauben, dass "es eine Verschwendung von Gedächtnis ist, eine einzige Null im Gedächtnis zu behalten"? Zunächst einmal, warum ist es Ihrer Meinung nach relevant, die Verwendung von vier Bytes Speicher in einem Prozess mit mindestens zwei Milliarden Bytes benutzeradressierbarem Speicher zu optimieren? Zweitens, genau welche Ressource wird Ihrer Meinung nach hier verbraucht ? Was meinst du damit, dass "Gedächtnis" verbraucht wird?
Die Antworten auf diese Fragen interessieren mich zum einen, weil Sie lernen können, wie falsch Ihr Verständnis von Optimierung und Speicherverwaltung ist, und zum anderen, weil ich immer wissen möchte, warum Anfänger bizarre Dinge glauben, damit ich sie entwerfen kann bessere Werkzeuge, um sie zu korrekten Überzeugungen zu führen.
quelle
Er hat recht. Du hast recht. Du liegst falsch.
Er hat begrifflich Recht, dass magische Zahlen vermieden werden sollten. Konstanten verbessern die Lesbarkeit des Codes, indem sie dem Kontext hinzufügen, was die Zahl bedeutet. Wenn in Zukunft jemand Ihren Code liest, weiß er, warum eine bestimmte Nummer verwendet wurde. Und wenn Sie einen Wert irgendwo später ändern müssen, ist es weitaus besser, ihn an einem Ort zu ändern, als überall dort zu suchen, wo eine bestimmte Zahl verwendet wird.
Davon abgesehen hast du recht. In diesem speziellen Fall glaube ich wirklich nicht, dass eine Konstante gerechtfertigt ist. Sie suchen den ersten Eintrag in der Liste, der immer Null ist. Es wird niemals 23. Oder -pi sein. Sie suchen gezielt nach Null. Ich glaube wirklich nicht, dass Sie den Code überladen müssen, indem Sie ihn zu einer Konstanten machen.
Sie liegen jedoch falsch, wenn Sie davon ausgehen, dass eine Konstante als Variable „mit Speicher belegt“ wird. Eine Konstante ist für den Menschen und den Compiler da. Er weist den Compiler an, diesen Wert während der Kompilierung an die Stelle zu setzen, an der Sie sonst eine Literalzahl eingegeben hätten. Und selbst wenn die Konstante im Speicher enthalten wäre, wäre der Effizienzverlust für alle Anwendungen außer den anspruchsvollsten nicht messbar. Sich Gedanken über die Speichernutzung einer einzelnen Ganzzahl zu machen, fällt definitiv in die "vorzeitige Optimierung".
quelle
Ich hätte die durch
0
eine Konstante ersetzt, um die Bedeutung klar zu machen, wie zNewVendorIndex
. Sie wissen nie, ob sich Ihre Bestellung ändern wird.quelle
Das ist die totale Präferenz Ihres Professors. Normalerweise verwenden Sie eine Konstante nur, wenn das Literal mehrmals verwendet wird, Sie möchten dem Leser klar machen, was der Zweck der Zeile ist, oder Ihr Literal wird möglicherweise in Zukunft geändert, und Sie möchten nur ändern es an einem Ort. In diesem Semester ist der Professor jedoch Chef, also würde ich es von nun an in dieser Klasse tun.
Gutes Training für die Geschäftswelt? Gut möglich.
quelle
Um ehrlich zu sein, obwohl ich nicht denke, dass Ihr Code die beste Vorgehensweise ist, ist sein Vorschlag ehrlich gesagt ein wenig grotesk.
In einer .NET-Combobox ist es üblicher, dem Element "Select .." einen leeren Wert zuzuweisen, während die tatsächlichen Elemente aussagekräftige Werte haben. Führen Sie dann Folgendes aus:
eher, als
quelle
Er ist nicht falsch darin, den Wert der Verwendung von Konstanten hervorzuheben, und Sie sind nicht falsch darin, Literale zu verwenden. Sofern er nicht betont hat, dass dies der erwartete Codierungsstil ist, sollten Sie keine Noten für die Verwendung von Literalen verlieren, da diese nicht schädlich sind. Ich habe überall so oft im kommerziellen Code verwendete Literale gesehen.
Sein Punkt ist jedoch gut. Auf diese Weise können Sie auf die Vorteile von Konstanten aufmerksam machen:
1-Sie schützen Ihren Code bis zu einem gewissen Grad vor versehentlichen Manipulationen
2-Wie @DeadMG in seiner Antwort sagt, wird derselbe Literalwert an vielen Stellen möglicherweise fälschlicherweise mit einem anderen Wert angezeigt - Konstanten bewahren also die Konsistenz.
3-Konstanten erhalten den Typ, sodass Sie nicht 0F verwenden müssen, um Null zu bedeuten.
4-Um das Lesen zu vereinfachen, verwendet COBOL ZERO als reserviertes Wort für den Wert Null (es ist jedoch auch möglich, das Literal Null zu verwenden). Daher ist es manchmal hilfreich, einem Wert einen Namen zu geben, z. B .: (Quelle: ms-Konstanten)
oder wie in deinem Fall (wie in @Michael Krussel Antwort gezeigt)
quelle
int weeks = 52
, es gibt keine 52 Wochen pro Jahr. Es gibt 52.142857142857146 Wochen im Jahr, und das ist die Zahl, auf der Sie die Brüche behalten sollten. Natürlich ist das Einzige, was in diesem ganzen Konstantensatz tatsächlich konstant ist, die Anzahl der Monate.Sie müssten es nur dann in eine Konstante setzen, wenn es eine komplexe Ableitung hat oder wenn es häufig wiederholt wird. Sonst ist ein wörtliches Wort in Ordnung. Alles in eine Konstante zu setzen ist totaler Overkill.
quelle
Wie bereits erwähnt, was ist, wenn sich die Position ändert? Sie könnten / sollten einen Code verwenden, anstatt sich auf den Index zu verlassen.
Also, wenn Sie Ihre Auswahlliste erstellen, endet sie mit HTML wie
Überprüfen Sie dann, anstatt zu prüfen
selectedIndex === 0
, ob der WertCREATECODE
in einer Konstanten enthalten ist und sowohl für diesen Test als auch beim Erstellen der Auswahlliste verwendet wurde.quelle
Ich würde es insgesamt loswerden. Setzen Sie einfach eine neue Schaltfläche neben die Auswahlliste. Doppelklicken Sie auf ein Element in der Liste, um es zu bearbeiten, oder klicken Sie auf die Schaltfläche. Lassen Sie die neue Funktionalität nicht in der Combobox vergraben. Dann wird die magische Zahl komplett entfernt.
Im Allgemeinen sollte jede wörtliche Zahl im Code als Konstante definiert werden, um die Zahl in einen Kontext zu setzen. Was bedeutet Null? In diesem Fall ist 0 = NEW_VENDOR. In anderen Fällen kann dies eine andere Bedeutung haben. Daher ist es für die Lesbarkeit und Wartbarkeit immer eine gute Idee, einen Zusammenhang herzustellen.
quelle
Wie bereits erwähnt, sollten Sie eine andere Methode als die Indexnummer verwenden, um das Kombinationsfeldelement zu identifizieren, das einer bestimmten Aktion entspricht. Oder Sie können den Index mit einer programmgesteuerten Logik finden und in einer Variablen speichern.
Der Grund, warum ich schreibe, ist Ihr Kommentar zur "Verwendung von Speicher". In C # werden wie in den meisten Sprachen Konstanten vom Compiler "gefaltet". Kompilieren Sie beispielsweise das folgende Programm, und untersuchen Sie die IL. Sie werden feststellen, dass all diese Zahlen es nicht einmal in die IL schaffen, geschweige denn in den Arbeitsspeicher des Computers:
resultierende IL:
Unabhängig davon, ob Sie eine Konstante, ein Literal oder ein Kilobyte Code mit Konstantenarithmetik verwenden, wird der Wert in der IL wörtlich behandelt.
Ein verwandter Punkt: Konstante Faltung gilt für String-Literale. Viele glauben, dass ein solcher Aufruf zu viel unnötige, ineffiziente Verkettung von Zeichenfolgen verursacht:
Aber schauen Sie sich die IL an:
Fazit: Operatoren mit konstanten Ausdrücken führen zu konstanten Ausdrücken, und der Compiler führt die gesamte Berechnung durch. Dies wirkt sich nicht auf die Laufzeitleistung aus.
quelle