C# — пример того, как не надо делать язык программирования.
C# очень странно относится к затенению переменных. Обычно он это запрещает. Вот такой код, например, не компилируется:
string x = "Hi";
if (true) {
string x = "Bye";
}
Вывод компилятора:
error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameterТут в if-блоке вводится новая переменная, которая перекрывает переменную выше. Однако компилятор C# (и это поведение описано в спецификации) смотрит только на включение имён в областях видимости, но не на то, когда они объявлены! Если переставить два оператора местами, код всё равно не компилируется:
if (true) {
string x = "Bye";
}
string x = "Hi";Также нельзя написать код, который перекрывает параметр метода:
void method(int x) {
int x = 10; // Ошибка
}Однако можно написать метод, который затеняет... Поля класса! Причём и локальными переменными, и аргументами:
class C {
int x;
int y;
void m(int y /* ок */) {
int x = 10; // тоже ок
}
}...но только до тех пор, пока поля класса не упоминаются в области видимости. Если упоминаются, то нельзя переиспользовать их имена:
using System;
class C {
int x;
void m() {
Console.WriteLine(x);
int x = 10; // Ошибка
}
}
...но можно во вложенных областях видимости:
using System;
class C {
int x;
void m() {
Console.WriteLine(x);
{
int x = 10; // ок
}
}
}
Какой простой, консистентный и полезный набор правил!
BTW раньше было ещё хуже.