Ist dies eine richtige Situation, um eine Konstante zu verwenden?

42

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.

Rot 5
quelle
32
Er ist dogmatisch. Magische Zahlen sollten im Allgemeinen vermieden werden. Ich denke, -1, 0 und 1 können als Ausnahmen von dieser Regel angesehen werden. Außerdem würde eine Konstante wie diese nicht mehr Platz
Dave Mooney
23
@ DaveMooney: Bist du sicher, dass du hier keine Knie-Ruck-Reaktion hast? Es ist wahr, dass Dinge wie die -1in str.indexOf(substr) != -1für " strenthält substr" 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?).
62
Sie müssen die Regeln lernen, bevor Sie die Regeln brechen können
Ryathal
12
Ich hatte diese Methode auf mich unerwartet scheitern. Die Liste wurde alphabetisch sortiert. Ich habe - - Create new - verwendet, damit die Bindestriche den ersten und fest codierten Index 0 für die CreateNew-Methode sortieren. Dann hat jemand einen Artikel hinzugefügt, der mit einem einfachen Anführungszeichen "Mein Artikel" beginnt , das vor Bindestrichen sortiert wird. Meine harte Codierung führte dazu, dass das Programm beim nächsten Laden der Liste abstürzte. Ich musste die Datendatei der Liste manuell ändern, um die Kundendaten wiederherzustellen.
Hand-E-Food
14
Sie können int.Zerostattdessen verwenden, um ihn glücklich zu machen :)
Paul Stovell

Antworten:

90

Die eigentliche korrekte Vorgehensweise in C # besteht darin, sich überhaupt nicht auf die Reihenfolge der ComboItems zu verlassen .

public partial class MyForm : Form
{
    private readonly object VENDOR_NEW = new object();

    public MyForm()
    {
        InitializeComponents();
        comboVendor.Items.Insert(0, VENDOR_NEW);
    }

    private void comboVendor_Format(object sender, ListControlConvertEventArgs e)
    {
        e.Value = (e.ListItem == VENDOR_NEW ? "Create New Vendor" : e.ListItem);
    }

    private void comboVendor_SelectedIndexChanged(object sender, EventArgs e)
    {
        if(comboVendor.SelectedItem == VENDOR_NEW)
        {
            //Special logic for selecting "create new vendor"
        }
        else
        {
            //Usual logic
        }
    }
}
BlueRaja - Danny Pflughoeft
quelle
22
Wenn dies C # ist, sollten Sie ALL_CAPS nicht für Konstanten verwenden. Konstanten sollten PascalCased sein - stackoverflow.com/questions/242534/…
Groky
4
@Groky: Warum ist das wichtig? Wen interessiert es, wie er seine Konstanten benennt? Dies ist zu 100% richtig, wenn er ALL_CAPS für Konstanten konsistent verwendet.
Marco-Fiset
4
@marcof: Nun, wenn die Konstanten Teil einer öffentlichen Schnittstelle sind, sollte er den MS-Benennungsrichtlinien folgen. Wenn nicht, sollte er zumindest frühzeitig Best Practice lernen.
Groky
2
Das ist immer noch falsch. Es verschiebt das Problem von einem Integer-Literal (Null) zu einem String-Literal (Create New Vendor). Bestenfalls ist das Problem jetzt "Was passiert, wenn sich das Etikett ändert" anstatt "Was passiert, wenn sich der Index ändert".
Freiheit
7
@Freiheit: Falsch. Die String-Konstante dient hier nur zur Anzeige. Es hat keinerlei Einfluss auf die Logik des Programms. Im Gegensatz zur Verwendung von magischen Werten / Strings zum Speichern des Programmstatus kann das Ändern dieses Strings (oder das Hinzufügen / Entfernen von Dingen aus der Liste) niemals zu Problemen führen.
BlueRaja - Danny Pflughoeft
83

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.

if (comboVendor.SelectedIndex == NewVendorIndex)

Die meisten kompilierten Sprachen ersetzen die Konstante zur Kompilierungszeit, sodass keine Leistungseinbußen auftreten.

Michael Krussel
quelle
5
Ich würde einen beschreibenden Code für das value-Attribut verwenden, anstatt mich auf einen Index zu verlassen, der sich ändern kann (das Verschieben der create-Option an den unteren Rand der Liste würde die konstante Methode absolut unterbrechen). Dann suchen Sie einfach diesen Code.
CaffGeek
1
@Chad Ich bin damit einverstanden, dass das Identifizieren von Steuerelementen anhand der Reihenfolge in einer GUI sehr zerbrechlich ist. Wenn die Sprache es unterstützt, dem GUI-Element einen Wert hinzuzufügen, der nachgeschlagen werden kann, würde ich das verwenden.
Michael Krussel
3
@solution weil das die Konvention ist.
Ikke
3
@Ikke Das ist definitiv nicht die Konvention. stackoverflow.com/questions/242534/…
SolutionYogi
1
Wenn wir über C # sprechen, dann ist NewVendorIndex die Konvention. Es steht im Einklang mit dem Rest des .NET-Stils.
2.
36

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.

Vielen Dank an Papathanasiou
quelle
+1 für den Hinweis, dass in diesem Fall die Mittel das Endergebnis rechtfertigen
Oliver Clare
@ Thanos- " Vergiss nicht, dass er ein Professor ist. Seine Aufgabe ist es, dir Codierung und Best Practices beizubringen. " Dies war bei meinem Professor nie der Fall. Ich würde sagen, seine Aufgabe ist es, Ihnen beizubringen, was die Abteilung nach Erstellung des Kurses für wichtig hält.
Ramhound
13

[...] Meine Top-Option (Index 0, der sich nie ändert) öffnet den Dialog "Neuen Anbieter erstellen".

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.

kba
quelle
2
-1, um auch nur die Leistung zu erwähnen. Selbst wenn ein Computer nicht optimiert ist, kann er Milliarden solcher Vorgänge ausführen, bevor der Benutzer dies bemerkt.
Boris Yankov
3
@Boris OP schien besorgt über die Verschwendung von Ressourcen zu sein, weshalb ich es erwähnte. Ich verstehe nicht, wie meine Antwort deswegen weniger richtig wäre.
kba
12

Er behauptet, dass die 0 eine Konstante sein sollte, und hat mich deswegen angedockt.

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.

Er behauptet, ich sollte überhaupt keine Literale in meinem Code verwenden.

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.

Die Sache ist, ich verstehe nicht, warum ich diesen Code in dieser Situation zu einer Konstanten machen möchte. Dieser Index wird sich nie ändern

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.

Es ist auch nichts, was Sie anpassen müssten.

"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 .

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.

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.

Eric Lippert
quelle
6

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".

GroßmeisterB
quelle
1
Ich hätte diese Antwort fast gestimmt, wenn nicht für den dritten Absatz behauptet worden wäre, dass die Verwendung von Literal 0 klar genug ist und keine Konstante gerechtfertigt ist. Eine viel bessere Lösung wäre gewesen, sich überhaupt nicht auf die Indizierung des Kombinationsfeld-Elements zu verlassen, sondern stattdessen auf den Wert des ausgewählten Elements. Magische Konstanten sind magische Konstanten, auch wenn sie 0 oder 3.14 sind oder wie auch immer - benennen Sie sie entsprechend, da dies den Code besser lesbar macht.
Roland Tepp
Es ist vielleicht besser, den Wert in der Liste zu verwenden, aber darum ging es in seiner Frage nicht. Seine Frage war, ob das eine angemessene Verwendung für eine Konstante war. Und wenn man im Zusammenhang mit der Benutzeroberfläche einen Vergleich mit 0 vornimmt (aus welchem ​​Grund auch immer - vielleicht sucht jemand nach dem ersten Element, unabhängig vom Wert), ist es meiner Meinung nach unnötig, an dieser Stelle eine Konstante zu verwenden.
GrandmasterB
Ich würde dem nicht zustimmen ... Wenn man sich nur den Code ansieht, ist es nie sofort ersichtlich, welche Bedeutung 0 hat - es könnte wirklich sein, dass er immer nach dem ersten Element in der Liste sucht und das ist es, aber dann ist es würde viel sauberer lesen, wenn der Vergleich stattdessen 'comboVendor.SelectedIndex == FirstIndex' wäre?
Roland Tepp
2

Ich hätte die durch 0eine Konstante ersetzt, um die Bedeutung klar zu machen, wie z NewVendorIndex. Sie wissen nie, ob sich Ihre Bestellung ändern wird.

Bernard
quelle
1

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.

Jonathan Henson
quelle
2
Ich bin nicht einverstanden mit dem Teil "Verwenden Sie eine Konstante nur, wenn das Literal mehrmals verwendet wird". Mit 0 (und vielleicht -1, 1) ist es oft klar, in den meisten Fällen ist es gut, einer Sache einen Namen zu geben, der beim Lesen des Codes viel klarer ist.
Johannes
1

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:

if (string.IsNullOrEmpty(comboVendor.SelectedValue))

eher, als

if (comboVendor.SelectedIndex == 0)
Carson63000
quelle
3
In Ihrem Beispiel ist null einfach ein anderes Literal. Das Herzstück dieser Lektion ist, dass Literale vermieden werden sollten.
am
@overslacked - In meinem Beispiel gibt es kein Null-Literal.
Carson63000
Selbst wenn es ein Null-Literal gab, ist Null ein akzeptables Literal. Ich glaube nicht einmal, dass es eine Möglichkeit gibt, zu überprüfen, ob ein Verweis auf ein Objekt Null ist, ohne zu überprüfen, ob es gleich Null ist.
Ramhound
Carson63000 - Ich bezog mich auf Ihre Verwendung von IsNullOrEmpty. Sie tauschen einen "magischen Wert" gegen einen anderen. @Ramhound - Null ist in einigen Fällen ein akzeptables Literal, keine Frage, aber ich glaube nicht, dass dies ein gutes Beispiel ist (mit Null oder Leerzeichen als magischem Wert).
Überhose
-1 für "ein bisschen grotesk". Sie haben zwar Recht, dass die Verwendung des Werts konventioneller und verständlicher wäre, aber wenn Sie den ausgewählten
Index verwenden
1

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)

class CalendarCalc
{
    const int months = 12;
    const int weeks = 52; //This is not the best way to initialize weeks see comment
    const int days = 365;

    const double daysPerWeek = (double) days / (double) weeks;
    const double daysPerMonth = (double) days / (double) months;
}

oder wie in deinem Fall (wie in @Michael Krussel Antwort gezeigt)

Keine Chance
quelle
2
Ist das nicht eine seltsame Definition für Tage pro Woche? Es gibt 7 Tage die Woche nicht 7.4287143
Winston Ewert
@ WinstonEwert, danke für deinen Kommentar. 365/52 = 7,01923076923077 = 7 + (1/52). Wenn Sie nun den Bruchteil entfernen und 7 * 52 berechnen, erhalten Sie 364 Tage, was nicht der korrekten Anzahl von Tagen in einem Jahr entspricht. Ein Bruch ist genauer als ein Verlust (da Sie das Ergebnis so formatieren können, dass 7 angezeigt wird, wenn Sie nur die Zahl anzeigen möchten). Wie auch immer, es war nur ein Beispiel von MS über Konstanten, aber Ihr Punkt ist interessant.
NoChance
1
Natürlich ist es nur ein Beispiel, aber ich widerspreche Ihrer Aussage, dass es genauer ist, den Bruch einzuschließen. Eine Woche ist definiert als 7 Tage. In Anbetracht Ihrer Definition sind 26 Wochen 182,5 Tage, was einfach nicht korrekt ist. Wirklich, das Problem ist dein 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.
Winston Ewert
0

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.

DeadMG
quelle
Nur wenn Sie das zweimal überlegen und den Code nie ändern müssen. Es ist wirklich einfach, Fehler zu erstellen, indem Sie einen von zwei Fällen ändern.
BillThor
0

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

<select>
    <option value='CREATE'>Create New Vendor...</option>
    <option value='1'>Existing Vendor</option>
    <option value='2'>Existing Vendor 2</option>
    <option value='3'>Existing Vendor 3</option>
</select>

Überprüfen Sie dann, anstatt zu prüfen selectedIndex === 0, ob der Wert CREATECODEin einer Konstanten enthalten ist und sowohl für diesen Test als auch beim Erstellen der Auswahlliste verwendet wurde.

CaffGeek
quelle
3
Wahrscheinlich ein guter Ansatz, aber da er C # verwendet, ist HTML nicht der hoffnungsvollste Beispielcode.
Winston Ewert
0

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.

Jon Raynor
quelle
0

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:

public class Program
{
    public static int Main()
    {
        const int a = 1000;
        const int b = a + a;
        const int c = b + 42;
        const int d = 7928345;
        return (a + b + c + d) / (-a - b - c - d);
    }
}

resultierende IL:

.method public hidebysig static 
    int32 Main () cil managed 
{
    .maxstack 1
    .locals init (
        [0] int32 CS$1$0000
    )

    IL_0000: nop
    IL_0001: ldc.i4.m1  // the constant value -1 to be returned.
    IL_0002: stloc.0
    IL_0003: br.s IL_0005

    IL_0005: ldloc.0
    IL_0006: ret
}

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:

public class Program
{
    public static int Main()
    {
        const string a = "a";
        const string b = a + a;
        const string c = "C";
        const string d = "Dee";
        return (a + b + c + d).Length;
    }
}

Aber schauen Sie sich die IL an:

IL_0000: nop
IL_0001: ldstr "aaaCDee"
IL_0006: callvirt instance int32 [mscorlib]System.String::get_Length()
IL_000b: stloc.0
IL_000c: br.s IL_000e
IL_000e: ldloc.0
IL_000f: ret

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.

phoog
quelle