Чому 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
Натомість ви зазвичай використовуєте їх для обмеження сфери дії деяких локальних змінних. Це додатково детально розроблено тут і тут . Подивіться на відповідь Жоао Анджело і відповідь Кріса Уолліса на прикладах коротких. Я вважаю, що те саме стосується деяких інших мов із синтаксисом у стилі С, але не те, що вони мали б відношення до цього питання.
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>
Тобто, "висловлювання може складатися з (різних речей) або початкової фігурної дужки, за якою слід список висловлювань (який може включати одне або декілька тверджень), після чого закрита фігурна дужка". IE " { }
блок може замінити будь-яке твердження, де завгодно". В тому числі в середині коду.
Якщо не допустити { }
блокування в будь-якому місці, де може йти одне твердження, насправді було б ускладнено визначення мови .
Оскільки C ++ (і java) допускає блокування коду без попереднього твердження.
C ++ дозволив їм, оскільки це зробив C.
Можна сказати, все зводиться до того, що дизайн програмної мови США (на основі С) виграв, а не європейської мовної програми (на основі Модули-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
Я усвідомлюю, що це можна вирішити більш елегантно, використовуючи методи для кожного рівня структури. Але знову ж таки, майте на увазі, що такі речі, як зразки розподільників даних, як правило, повинні бути швидкими.
Отже, навіть незважаючи на те, що наведений вище код виконується лінійно, структура коду представляє "реальну" структуру об'єктів, що полегшує розуміння, підтримку та розширення інших розробників.