C# время жизни переменной в try finally

Я получил следующий код

screenshot

Почему x в finally-block имеет значение 5 вместо того, чтобы быть "уже определенным" или иметь значение по умолчанию 0?

5 ответов


Я думаю, вы установили точку останова в finally и посмотрел на x. x не имеет значения в соответствии со спецификацией языка C#, но отладчик, вероятно, посмотрел на место хранения, что первый x показал вам его значение.

в реальном коде вы не сможете прочитать из x на finally.

отладчик не подчиняется правилам языка.


жизнь x внутри {...} блок, try в вашем случае; однако, так как нет ноль-инициализации of локальные переменные в .Net следующий x содержит корзина, бывшая x стоимостью

try
{
   int x = 5;
}
finally
{
   // x is re-declared; since x is local it contains trash;
   // former x was aquired at the stack, so .Net just moves stack pointer 
   // and doesn't remove former x value
   int x; 
   ...
}

http://msdn.microsoft.com/en-us/library/aa691170 (v=против 71).aspx

...Локальная переменная автоматически не инициализируется и так не имеет значения по умолчанию значение...

http://msdn.microsoft.com/en-us/library/aa664742 (v=против 71).aspx

...Область действия локальной переменной, объявленной в объявлении локальной переменной - это блок, в котором декларация происходит...


вы наверное используйте отладчик visual studio, который ретранслирует имена переменных для просмотра значений и показывает неправильное значение в таких запутанных случаях.


область действия переменной x ограничен try блок только, да отладчик показывает значение 5, но если вы пытаетесь использовать x переменная вы столкнетесь с проблемами, которые вы упомянули.

Попробуйте Это:

finally
{
   int x;
   Console.Write(x); //error use of unassigned local variable
}

почему x в finally-block значение 1 вместо того, чтобы быть "уже определено" или имеет значение по умолчанию 0?

то, что вы видите, - это отладчик, связывающий символы. Он вообще не имеет значения, и на самом деле, если вы попытаетесь его использовать, вы получите ошибку неназначенной переменной.

теперь, почему он не показывает, как уже определено, это другой вопрос. Ответ в том, что {} определение пространства. (В C# определяются переменные на уровне филиалов, а не на уровне функций). Они находятся в двух разных пространствах объявления, и поэтому это разрешено. Первый x не может разлиться туда, где второй x определяется.

что ты иная, чем

void foo () {
 var x = 2;

 if (true){
   var x = 3;
 }

}

что запрещено.