Возьмем следующий код:
class Foo
{
string bar;
public void Method()
{
if (!String.IsNullOrEmpty(this.bar))
{
string bar = "Hello";
Console.Write(bar);
}
}
}
Это скомпилируется, и все хорошо. Однако теперь удалим префикс this.
:
class Foo
{
string bar;
public void Method()
{
if (!String.IsNullOrEmpty(bar)) // <-- Removed "this."
{
string bar = "Hello";
Console.Write(bar);
}
}
}
В этом случае я получаю ошибку компилятора. Я согласен, что это ошибка, однако это место ошибки, которая меня смущает. Ошибка на линии:
string bar = "Hello";
С сообщением:
Локальная переменная с именем "bar" не может быть объявлена в этой области, потому что это означало бы другое значение для "бара", которое уже используется в "родительская или текущая" область для обозначения чего-то еще
Из того, что я понимаю о компиляторе, объявление bar
поднимается вверху метода Method()
. Однако, если в этом случае строка:
if (!String.IsNullOrEmpty(bar))
Должно считаться неоднозначным, поскольку bar
может быть ссылкой на поле экземпляра или на локальную переменную, еще не объявленную.
Мне кажется странным, что удаление this.
может привести к ошибке компиляции в другой строке. Другими словами, объявление локальной переменной bar
вполне допустимо, если до сих пор в области не были сделаны потенциально неоднозначные ссылки на bar
(заметьте, если я прокомментирую if (!String.IsNullOrEmpty(bar))
, тогда ошибка исчезнет).
Что все кажется довольно педантичным, так что ваш вопрос?:
Мой вопрос в том, почему компилятор допускает неоднозначную ссылку на переменную до ее объявления в области, но затем флага сама декларация является избыточной. Должна ли двусмысленная ссылка на bar
в String.IsNullOrEmpty()
быть более точным местом ошибки? В моем примере это, конечно, легко заметить, но когда я столкнулся с этой проблемой в дикой природе, ссылка была страница вверх и намного сложнее отслеживать.