Warum kann ich eine Klasse mit dem Namen "var" erstellen?

103

Ist kein varSchlüsselwort in C #? Aber warum kann ich das tun:

public class var { }

public class main
{
    public static void main(string[] args)
    {
        var testVar = new var();
    }
}

Das varim Code verwendete ist die varKlasse, die vor der mainKlasse deklariert wird . Und der Compiler beschwert sich nicht einmal.

Während, wenn ich das mache:

public class int { }

oder dieses:

public class true { }

Der Compiler sagte, dass intoder trueein Schlüsselwort ist und nicht so verwendet werden kann. Warum ist es nicht dasselbe mit var?

John Isaiah Carmona
quelle
6
Warum willst du? So verwirrend und schwer zu lesen.
Duffymo
31
sehr gute Frage!
Richard
50
Sie können dies auch var var = "var";in einer Methode tun . Immerhin ist Freitag.
Henk Holterman
11
Ich vermute, sie haben es auf diese Weise geschafft, abwärtskompatibel mit Code zu sein, bevor "var" etwas Besonderes bedeutete.
Vidstige

Antworten:

101

varist kein Schlüsselwort gemäß dieser Liste .

Da es sich um ein kontextbezogenes Schlüsselwort handelt, kann der Compiler anhand des Kontexts entscheiden, welche Ihre Klasse und welches das kontextbezogene Schlüsselwort ist, und es entsteht keine Verwirrung.

Ein kontextbezogenes Schlüsselwort lautet:

wird verwendet, um eine bestimmte Bedeutung im Code anzugeben, ist jedoch kein reserviertes Wort in C #.

Da es nicht reserviert ist, können Sie es verwenden.

Wie in den obigen Kommentaren erwähnt, gibt es eine Diskussion der Unterschiede sowie eine Liste der verschiedenen Schlüsselwörter und Kontextschlüsselwörter, die in jeder Version von c # im Eric Lipperts-Blog hinzugefügt wurden

Es ist interessant festzustellen, dass seit der Festlegung der Schlüsselwörter in C # 1.0 keine Ergänzungen vorgenommen wurden, um die Abwärtskompatibilität zu gewährleisten.

Sam Holder
quelle
1
Allerdings ist es hier unter "C # Keywords" kategorisiert msdn.microsoft.com/en-us/library/bb383973.aspx ... verwirrend!
Richard
4
Aber es ist ein Contextual Keyword. "Ein kontextbezogenes Schlüsselwort wird verwendet, um eine bestimmte Bedeutung im Code bereitzustellen. Es ist jedoch kein reserviertes Wort in C # . Einige kontextbezogene Schlüsselwörter, z. B. teilweise und wo, haben in zwei oder mehr Kontexten eine besondere Bedeutung."
Tim Schmelter
5
@ TimSchmelter Dann ist "var" ein "Schlüsselwort". Nur kein "reserviertes Wort", oder?
luiscubal
2
Ich vermute, es geht darum, die Kompatibilität mit altem Code aufrechtzuerhalten - wenn jemand eine Klasse mit dem Namen varhatte, bricht beim Upgrade von C # nicht alles zusammen.
Callum Rogers
1
@ CallumRogers: Genau deshalb hat das C # -Team dies getan. Gleiches gilt für andere später eingeführte "Schlüsselwörter" wie from, join etc (übrigens alle kontextbezogen).
Abel
18

Der Compiler ist klug genug zu wissen, dass der Kontext, den Sie varals Klassennamen verwenden, niemals ein Kontext für das Schlüsselwort ist, sodass dies zulässig ist (weshalb er als kontextbezogenes Schlüsselwort definiert ist ).

Oded
quelle
Ich denke, diese Antwort ist zumindest etwas irreführend. Der Compiler ist nicht genau "klug genug", um zu bestimmen, ob varer als Schlüsselwort in Code wie verwendet wird var testVar = new var();. Ja, der Kontext in Bezug darauf, ob ein benutzerdefinierter Typ mit dem Namen vardefiniert wurde, spielt darin eine Rolle , aber genau deshalb, weil der Compiler in diesen Fällen nicht klug genug ist, um zu wissen, ob er var testVarsich auf die Klasse varoder auf das Schlüsselwort bezieht, das varer standardmäßig auf die Klasse verwendet in einem solchen Kontext. Wäre das varSchlüsselwort anders benannt, könnte es im selben "Kontext" verwendet werden.
ODER Mapper
Vergleichen Sie dies mit anderen kontextbezogenen Schlüsselwörtern wie add- hier - der Compiler weiß tatsächlich bei jedem Auftreten, ob das Schlüsselwort gemeint ist (Ereignisdeklaration; Bezeichner würde dort keinen Sinn ergeben) oder ob sich der Code auf einen Bezeichner bezieht (Typ oder Name in einer Deklaration, Verwendung des Bezeichners innerhalb eines Methodenkörpers (Schlüsselwort würde dort keinen Sinn ergeben).
ODER Mapper
12

Eine andere Sichtweise: "var" als Schlüsselwort war nicht in den ersten Versionen von C # enthalten (im Gegensatz zu "int" und "true"), daher haben Sie möglicherweise Code geschrieben, der eine Klasse namens "var" hatte. Das war vollkommen in Ordnung und legal. Später, als "var" zur Sprache hinzugefügt wurde, waren die Designer so freundlich, dass sie nur in bestimmten Kontexten zu einem Schlüsselwort wurden, sodass Ihre vorhandene var-Klasse weiterhin funktioniert.

Dies ist eine der wirklichen Herausforderungen beim Sprachdesign - wie man neue Funktionen hinzufügt, ohne vorhandenen Code zu beschädigen und ohne die Verwendung der neuen Funktionen umständlich zu machen.

Polyfun
quelle
8

In C # -Versionen vor Version 3 wurden implizit typisierte lokale Variablen noch nicht unterstützt, varhatten also keine besondere Bedeutung und es war möglich, benannte Variablen und Klassen zu definieren var. Ihr Beispielprogramm ist legal, weil beide Vorkommen von varin mainder Klasse bezeichnet var.

C # 3 und spätere Versionen sind abwärtskompatibel, sodass in C # geschriebener Code vor Version 3 weiterhin mit den neuen Compilern kompiliert wird.

intund truesind Schlüsselwörter seit C # 1.

dtb
quelle
3

Schlüsselwörter können kontextbezogen reserviert werden. Wenn der Quellcode analysiert wird, wird dieser Kontext als Teil des Analysebaums eingerichtet. Die Bewertung der Schlüsselwörter erfolgt in diesem Kontext. In diesem Fall befindet sich var also nicht in einem reservierten Kontext und hat nicht die gleiche Bedeutung wie bei der Verwendung in einer Zuweisungsanweisung. Ich glaube, ein Grund für diese Flexibilität ist, dass var in C # 3 eingeführt wurde. Wenn Sie es also überall reservieren, kann es in einigen Programmen zu einer Unterbrechung der Abwärtskompatibilität kommen, während die Verwendung als Deklaration für Variablentypen in früheren Versionen nicht kompiliert worden wäre Bruch.

pfries
quelle