web-dev-qa-db-ger.com

Warum erlaubt C # {} Codeblöcke ohne vorherige Anweisung?

Warum erlaubt C # Codeblöcke ohne vorherige Anweisung (z. B. if, else, for, while)?

void Main()
{
    {   // any sense in this?
        Console.Write("foo");
    }
}
83
Seldon

In dem von Ihnen gegebenen Kontext gibt es keine Bedeutung. Das Schreiben einer konstanten Zeichenfolge in die Konsole funktioniert überall im Programmablauf auf dieselbe Weise.1

Stattdessen verwenden Sie sie normalerweise, um den Umfang einiger lokaler Variablen einzuschränken. Dies wird weiter ausgeführt hier und hier . In João Angelos Antwort und Chris Wallis Antwort finden Sie kurze Beispiele. Ich glaube, dasselbe gilt auch für andere Sprachen mit C-Stil-Syntax, nicht jedoch, dass sie für diese Frage relevant sind.


1Es sei denn, Sie entscheiden sich zu versuchen, lustig zu sein, und erstellen Ihre eigene Console-Klasse mit einer Write()-Methode, die etwas völlig unerwartetes bewirkt.

87
BoltClock

Der { ... } hat zumindest den Nebeneffekt, einen neuen Geltungsbereich für lokale Variablen einzuführen.

Ich neige dazu, sie in switch-Anweisungen zu verwenden, um für jeden Fall einen anderen Geltungsbereich bereitzustellen. Auf diese Weise kann ich lokale Variablen mit dem gleichen Namen am nächstmöglichen Ort ihrer Verwendung definieren und angeben, dass sie nur auf Fallebene gültig sind .

141
João Angelo

Es ist nicht so sehr ein feature von C # als ein logischer Nebeneffekt vieler C-Syntaxsprachen, die geschweifte Klammern zu Definieren des Gültigkeitsbereichs verwenden.

In Ihrem Beispiel haben die geschweiften Klammern überhaupt keine Auswirkungen, aber im folgenden Code definieren sie den Gültigkeitsbereich und damit die Sichtbarkeit einer Variablen:

Dieses ist erlaubt, da i im ersten Block außerhalb des Gültigkeitsbereichs liegt und im nächsten erneut definiert wird:

{
    {
        int i = 0;
    }

    {
        int i = 0;
    }
}

Dieses ist nicht erlaubt, da ich aus dem Gültigkeitsbereich herausgefallen ist und im äußeren Gültigkeitsbereich nicht mehr sichtbar ist:

{
    {
        int i = 0;
    }

    i = 1;
}

Und so weiter und so weiter.

55
Chris Wallis

Ich betrachte {} als eine Anweisung, die mehrere Anweisungen enthalten kann.

Stellen Sie sich eine if -Anweisung vor, die aus einem booleschen Ausdruck gefolgt von one -Anweisung besteht. Dies würde funktionieren:

if (true) Console.Write("FooBar");

Das würde auch funktionieren:

if (true)
{
  Console.Write("Foo");
  Console.Write("Bar");
}

Wenn ich mich nicht irre, spricht man von einer Blockanweisung.

Da {} andere Anweisungen enthalten kann, kann es auch andere {}. Enthalten. Der Gültigkeitsbereich einer Variablen wird durch ihren übergeordneten {} (Blockanweisung) definiert.

Der Punkt, den ich versuche zu machen, ist, dass {} nur eine Aussage ist, also erfordert es kein ob oder was auch immer ...

17
RBaarda

Die allgemeine Regel in C-Syntax-Sprachen lautet: "Alles, was zwischen { } steht, sollte als eine einzige Anweisung behandelt werden, und es kann dorthin gehen, wo eine einzelne Anweisung verwendet werden könnte":

  • Nach einer if.
  • Nach einer for, while oder do.
  • Überall im Code .

Für alle Absichten und Zwecke ist dies die Sprachgrammatik:

     <statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>

Das heißt, "eine Anweisung kann aus (verschiedenen Dingen) oder aus einer öffnenden Klammer bestehen, gefolgt von einer Anweisungsliste (die eine oder mehrere Anweisungen enthalten kann), gefolgt von einer geschlossenen Klammer". I.E. msgstr "Ein { } - Block kann jede Anweisung überall ersetzen". Einschließlich in der Mitte des Codes.

Wenn ein { }-Block nicht an einer beliebigen Stelle zulässig ist, hätte dies die Sprachdefinition komplexer gemacht.

11
Massimo

Weil C++ (und Java) Codeblöcke ohne vorherige Anweisung zulassen.

C++ erlaubte ihnen, weil C es tat.

Man könnte sagen, dass alles auf die Tatsache zurückzuführen ist, dass das Design der USA-Programmsprache (C-basiert) nicht das der europäischen Programmsprache ( Modula-2 /) gewonnen hat.

(Steueranweisungen wirken auf eine einzige Anweisung, Anweisungen können Gruppen sein, um neue Anweisungen zu erstellen.)

1
Ian Ringrose
// if (a == b)
// if (a != b)
{
    // do something
}
1
user202448

Sie haben gefragt, "warum" C # Codeblöcke ohne vorherige Anweisungen zulässt. Die Frage "warum" könnte auch als "Was ist der mögliche Nutzen dieses Konstrukts?"

Ich persönlich verwende aussagekräftige Codeblöcke in C #, in 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 den folgenden Codeausschnitt, der 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 mit Methoden für jede Strukturebene eleganter gelöst werden könnte. Denken Sie jedoch auch daran, dass Dinge wie Setzer für Beispieldaten normalerweise schnell sein müssen.

Auch wenn der obige Code linear ausgeführt wird, stellt die Codestruktur die "reale" Struktur der Objekte dar und erleichtert damit anderen Entwicklern das Verständnis, die Wartung und die Erweiterung.

0
Marco

1 Weil ... es den Gültigkeitsbereich der - Anweisung beibehält .. oder Funktion. Dies ist wirklich nützlich, um den großen Code zu managen.

{
    {
        // Here this 'i' is we can use for this scope only and out side of this scope we can't get this 'i' variable.

        int i = 0;
    }

    {
        int i = 0;
    }
}

enter image description here

0
Raj