Почему С# разрешает кодовые блоки без предшествующего оператора (например, if
, else
, for
, while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
Почему С# разрешает кодовые блоки без предшествующего оператора (например, if
, else
, for
, while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
В контексте, который вы даете, нет никакого значения. Запись постоянной строки в консоль будет работать одинаково в любом месте потока программы. 1
Вместо этого вы обычно используете их для ограничения объема некоторых локальных переменных. Это далее описано здесь и здесь. Посмотрите на ответ Жоао Анджелоса и ответ Криса Уоллисса для кратких примеров. Я считаю, что то же самое относится и к некоторым другим языкам с синтаксисом C-стиля, а не к тому, что они будут иметь отношение к этому вопросу.
1 Если, конечно, вы не решите попробовать смешно и создать свой собственный класс Console
с помощью метода Write()
, который сделает что-то совершенно неожиданное.
{ ... }
имеет по крайней мере побочный эффект введения новой области для локальных переменных.
Я обычно использую их в операторах switch
для предоставления различной области для каждого случая и таким образом позволяя мне определять локальную переменную с тем же именем в ближайшем возможном месте их использования и также означать, что они только действителен на уровне корпуса.
Это не столько особенность С#, сколько логический побочный эффект многих языков синтаксиса Си, которые используют фигурные скобки для define scope.
В вашем примере скобки не имеют никакого эффекта, но в следующем коде они определяют область видимости и, следовательно, видимость переменной:
Этот разрешен, поскольку я выпадает из области видимости в первом блоке и снова определяется в следующем:
{
{
int i = 0;
}
{
int i = 0;
}
}
Этот не разрешен, поскольку я выпал из области видимости и больше не отображается во внешней области:
{
{
int i = 0;
}
i = 1;
}
И так далее и т.д.
Я рассматриваю {}
как инструкцию, которая может содержать несколько операторов.
Рассмотрим оператор if, который существует из булевского выражения, за которым следует оператор один. Это будет работать:
if (true) Console.Write("FooBar");
Это также сработает:
if (true)
{
Console.Write("Foo");
Console.Write("Bar");
}
Если я не ошибаюсь, это называется оператором блока.
Так как {}
может содержать другие операторы, он также может содержать другие {}
.
Область действия переменной определяется ей parent {}
(оператор блока).
То, что я пытаюсь сделать, состоит в том, что {}
- это просто оператор, поэтому для него не требуется if или что-то еще...
Общее правило в языках синтаксиса C: "что-либо между { }
должно рассматриваться как один оператор, и оно может идти везде, где может быть один оператор":
if
.for
, while
или do
.Во всех смыслах и целях это как грамматика языка включало это:
<statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>
То есть "оператор может состоять из (разных вещей) или открывающей скобки, за которым следует список операторов (который может включать одно или несколько операторов), за которым следует закрытая скобка". И.Е. "Блок { }
может заменить любой оператор в любом месте". В том числе в середине кода.
Не позволяя блоку { }
в любом месте, где может работать один оператор, действительно сделает определение языка более сложным.
Поскольку С++ (и java) допускает блоки кода без предшествующего оператора.
С++ допустил их, потому что C сделал.
Можно сказать, что все сводится к тому, что дизайн программ на языке США (на основе C) выиграл, а не европейский программный язык (Modula-2).
(Управляющие операторы действуют на один оператор, операторы могут быть группами для создания новых операторов)
// if (a == b)
// if (a != b)
{
// do something
}
1 Поскольку... Поддерживает область области действия statement.. или Function, Это действительно полезно для mane большого кода.
{
{
// 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;
}
}