Warum C # ermöglicht Codeblöcke ohne vorherige Anweisung (zB if
, else
, for
, while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
Warum C # ermöglicht Codeblöcke ohne vorherige Anweisung (zB if
, else
, for
, while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
Antworten:
In dem von Ihnen angegebenen Kontext gibt es keine Bedeutung. Das Schreiben einer konstanten Zeichenfolge in die Konsole funktioniert überall im Programmablauf auf die gleiche Weise. 1
Stattdessen verwenden Sie sie normalerweise, um den Umfang einiger lokaler Variablen einzuschränken. Dies wird hier und hier weiter ausgeführt . Schauen Sie sich João Angelos Antwort und Chris Wallis 'Antwort für kurze Beispiele an. Ich glaube, dass dies auch für einige andere Sprachen mit C-Syntax gilt, jedoch nicht, dass sie für diese Frage relevant wären.
1 Es sei denn, Sie beschließen natürlich, lustig zu sein und Ihre eigene Console
Klasse mit einer Write()
Methode zu erstellen , die etwas völlig Unerwartetes bewirkt.
out
Parameter an eine geschriebene Schnittstellenimplementierung zu übergeben in einer anderen Sprache, und diese Implementierung liest die Variable vor dem Schreiben.
Dies { ... }
hat zumindest den Nebeneffekt, dass ein neuer Bereich für lokale Variablen eingeführt wird.
Ich neige dazu, sie in switch
Anweisungen zu verwenden, um für jeden Fall einen anderen Bereich bereitzustellen und auf diese Weise die Möglichkeit zu geben, lokale Variablen mit demselben Namen am nächstmöglichen Ort ihrer Verwendung zu definieren und auch anzuzeigen, dass sie nur auf der Ebene des Falls gültig sind.
{}
, damit diese goldenen Abzeichen kommen ... :)
Es ist weniger ein Merkmal von C # als vielmehr ein logischer Nebeneffekt vieler C-Syntaxsprachen, die Klammern verwenden, um den Bereich zu definieren .
In Ihrem Beispiel haben die geschweiften Klammern überhaupt keine Auswirkung, aber im folgenden Code definieren sie den Umfang und damit die Sichtbarkeit einer Variablen:
Dies ist zulässig, da ich im ersten Block aus dem Gültigkeitsbereich herausfalle und im nächsten erneut definiert werde:
{
{
int i = 0;
}
{
int i = 0;
}
}
Dies ist nicht erlaubt, da ich aus dem Bereich gefallen bin und im äußeren Bereich nicht mehr sichtbar ist:
{
{
int i = 0;
}
i = 1;
}
Und so weiter und so fort.
{}
Klammern genannt?
One of two marks of the form [ ] or ( ), and in mathematical use also {}, used for enclosing a word or number of words, a portion of a mathematical formula, or the like, so as to separate it from the context;
In jedem Fall handelt es sich nicht um Klammern, sondern um eine geschweifte Klammer.
Ich betrachte {}
als eine Aussage, die mehrere Aussagen enthalten kann.
Stellen Sie sich eine if-Anweisung vor, die aus einem booleschen Ausdruck gefolgt von einer Anweisung besteht. Das würde funktionieren:
if (true) Console.Write("FooBar");
Dies würde auch funktionieren:
if (true)
{
Console.Write("Foo");
Console.Write("Bar");
}
Wenn ich mich nicht irre, wird dies als Blockanweisung bezeichnet.
Da {}
kann andere Anweisungen enthalten, kann es auch andere enthalten {}
. Der Bereich einer Variablen wird durch ihre übergeordnete Variable {}
(Blockanweisung) definiert.
Der Punkt, den ich versuche zu machen, ist, dass dies {}
nur eine Aussage ist, also erfordert es kein Wenn oder was auch immer ...
Die allgemeine Regel in C-Syntaxsprachen lautet: "Alles dazwischen { }
sollte als einzelne Anweisung behandelt werden und kann überall dort eingesetzt werden, wo eine einzelne Anweisung dies könnte."
if
.for
, while
oder do
.In jeder Hinsicht ist es so, wie es die Sprachgrammatik beinhaltet:
<statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>
Das heißt, "eine Anweisung kann aus (verschiedenen Dingen) oder einer öffnenden Klammer bestehen, gefolgt von einer Anweisungsliste (die eine oder mehrere Anweisungen enthalten kann), gefolgt von einer geschlossenen Klammer". IE "a{ }
Block kann jede Anweisung überall ersetzen". Einschließlich in der Mitte des Codes.
Wenn ein { }
Block nirgendwo zugelassen wird, wo eine einzelne Anweisung hingehen kann, wäre die Sprachdefinition komplexer geworden .
Weil C ++ (und Java) Codeblöcke ohne vorhergehende Anweisung zuließen.
C ++ erlaubte es ihnen, weil C. es tat.
Man könnte sagen, dass alles auf die Tatsache zurückzuführen ist, dass das Design der US-Programmsprache (C-basiert) eher gewonnen hat als die europäische Programmsprache ( Modula-2) basiert).
(Steueranweisungen wirken sich auf eine einzelne Anweisung aus. Anweisungen können Gruppen sein, um neue Anweisungen zu erstellen.)
// if (a == b)
// if (a != b)
{
// do something
}
Sie haben gefragt, warum C # Codeblöcke ohne vorherige Anweisungen zulässt. Die Frage "warum" könnte auch als "was wären mögliche Vorteile dieses Konstrukts?" Interpretiert werden.
Persönlich verwende ich in C # anweisungslose Codeblöcke, bei denen die Lesbarkeit für andere Entwickler erheblich verbessert wird, wobei zu beachten ist, dass der Codeblock den Umfang lokaler Variablen einschränkt. Betrachten Sie beispielsweise das folgende Codefragment, das dank der zusätzlichen Codeblöcke viel einfacher zu lesen ist:
OrgUnit world = new OrgUnit() { Name = "World" };
{
OrgUnit europe = new OrgUnit() { Name = "Europe" };
world.SubUnits.Add(europe);
{
OrgUnit germany = new OrgUnit() { Name = "Germany" };
europe.SubUnits.Add(germany);
//...etc.
}
}
//...commit structure to DB here
Mir ist bewusst, dass dies eleganter gelöst werden könnte, indem Methoden für jede Strukturebene verwendet werden. Denken Sie jedoch auch daran, dass Dinge wie Beispieldatensämaschinen normalerweise schnell sein müssen.
Obwohl der obige Code linear ausgeführt wird, stellt die Codestruktur die "reale" Struktur der Objekte dar, wodurch andere Entwickler das Verstehen, Verwalten und Erweitern erleichtern können.