Почему С# разрешает инструкции после случая, но не раньше?
Почему С# разрешает это:
var s = "Nice";
switch (s)
{
case "HI":
break;
const string x = "Nice";
case x:
Console.Write("Y");
break;
}
Но не это:
var s = "Nice";
switch (s)
{
const string x = "Nice";
case x:
Console.Write("Y");
break;
}
Ответы
Ответ 1
Поскольку ваш отступы вводят в заблуждение, первый код на самом деле:
var s = "Nice";
switch (s)
{
case "HI":
break;
const string x = "Nice";
case x:
Console.Write("Y");
break;
}
То есть x
объявляется внутри оператора case
(хотя после break
), где он действителен. Однако непосредственно внутри оператора switch
его значение недействительно - единственными действительными утверждениями являются case
и default
.
Кроме того, объявления const
оцениваются во время компиляции, поэтому x
определяется, даже если это предложение a break
.
Однако обратите внимание, что компилятор Mono С# не компилирует этот код, он жалуется, что "имя" x
не существует в текущей области ", поэтому Mono, похоже, выполняет больше проверок, чем компилятор .NET. Однако я не могу найти какие-либо правила в стандарте С#, которые запрещают это использование объявления const
, поэтому я предполагаю, что компилятор .NET прав, а компилятор Mono ошибочен.
Ответ 2
Поскольку спецификация языка не позволяет const непосредственно в вашем коммутаторе (разрешены только случай и значение по умолчанию):
switch (expression)
{
case constant-expression:
statement
jump-statement
[default:
statement
jump-statement]
}
Где:
expression:
Интегральное или строковое выражение.
statement:
Встроенный оператор (ы), который должен быть выполнен, если управление передано в случае или по умолчанию.
jump-statement:
Оператор перехода, который передает управление из корпуса.
constant-expression:
Управление передается в конкретный случай в соответствии со значением этого выражения.
В первом случае const является частью вашей логики case. Команда const будет работать только потому, что она переписывается в compiletime, а не во время выполнения.
Ответ 3
... потому что switch
делает это
jump_to_the_label_matchig(s)
{
label1:
...
done_quit_this;
label2:
...
done_quit_this;
d'oh:
...
done_quit_this;
}
а не
now_jump_to_the_label_matchig(s)
{
le'mme_wander_around_doing_things_that_could_have_been_done_before_me;
label1:
...
done_quit_this;
label2:
...
Я уверен, что если бы это было разрешено, вы бы нашли людей, готовых сделать все свое программирование там: -)