Рассмотрим следующий источник:
static void Main(string[] args)
{
bool test;
Action lambda = () => { test = true; };
lambda();
if (test)
Console.WriteLine("Ok.");
}
Он должен скомпилировать, правильно? Ну, это не так. Мой вопрос: согласно стандарту С#, должен ли этот код компилироваться или это ошибка компилятора?
Сообщение об ошибке:
Use of unassigned local variable 'test'
Примечание: Я знаю, как исправить ошибку, и я частично знаю, почему это происходит. Однако локальная переменная назначается безоговорочно, и я предполагаю, что компилятор должен это заметить, но это не так. Интересно, почему.
Комментарий к ответам: С# позволяет объявлять неназначенные переменные и это действительно полезно, т.е.
bool cond1, cond2;
if (someConditions)
{
cond1 = someOtherConditions1;
cond2 = someOtherConditions2;
}
else
{
cond1 = someOtherConditions3;
cond2 = someOtherConditions4;
}
Компилятор правильно компилирует этот код, и я думаю, что оставшиеся переменные неназначенные фактически делают код немного лучше, потому что:
- Он сообщает читателю, что значения назначаются позже (главным образом, вероятно, в следующем условном выражении)
- Заставляет программиста назначать переменные во всех ветвях внутренних условий (если это была цель этого кода с самого начала), потому что компилятор откажется от компиляции кода, если одна из ветвей не назначает одну из них.
На полях: Это еще более интересно. Рассмотрим тот же пример в С++:
int main(int argc, char * argv[])
{
bool test;
/* Comment or un-comment this block
auto lambda = [&]() { test = true; };
lambda();
*/
if (test)
printf("Ok.");
return 0;
}
Если вы прокомментируете блокировку, компиляция заканчивается предупреждением:
main.cpp(12): warning C4700: uninitialized local variable 'test' used
Однако, если вы удалите комментарий, компилятор не выдаст никаких предупреждений. Мне кажется, что он может определить, если переменная задана в конце концов.