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