Неявно типизированные
локальные переменные
В C# поддерживается возможность определения типа используемых в методе ло-
кальных переменных по типу используемого при их инициализации выражения:Неявно типизированные локальные переменные
249
private static void ImplicitlyTypedLocalVariables() {
var name = "Jeff";
ShowVariableType(name); // Вывод: System.String
// var n = null; // Ошибка
var x = (String)null; // Допустимо, хотя и бесполезно
ShowVariableType(x); // Вывод: System.String
var numbers = new Int32[] { 1, 2, 3, 4 };
ShowVariableType(numbers); // Вывод: System.Int32[]
// Меньше символов при вводе сложных типов
var collection = new Dictionary<String, Single>() { { "Grant", 4.0f } };
// Вывод: System.Collections.Generic.Dictionary`2[System.String,System.Single]
ShowVariableType(collection);
foreach (var item in collection) {
// Вывод: System.Collections.Generic.KeyValuePair`2
[System.String,System.Single]
ShowVariableType(item);
}
}
private static void ShowVariableType<T>(T t) {
Console.WriteLine(typeof(T));
}
Первая строка кода метода ImplicitlyTypedLocalVariables вводит новую ло-
кальную переменную при помощи ключевого слова var . Чтобы определить ее тип,
компилятор смотрит на тип выражения с правой стороны от оператора присваивания
( = ). Так как "Jeff" — это строка, компилятор присваивает переменной name тип
String . Чтобы доказать, что компилятор правильно определяет тип, я написал уни-
версальный метод ShowVariableType . Он определяет тип своего аргумента и выводит
его на консоль. Для простоты чтения выводимые методом ShowVariableType значе-
ния я добавил в виде комментариев внутрь метода ImplicitlyTypedLocalVariables .
Вторая операция присваивания (закомментированная) в методе ImplicitlyType
dLocalVariables во время компиляции привела бы к ошибке (ошибка CS0815:
невозможно присвоить значение null локальной переменной с неявно заданным
типом):
error CS0815: Cannot assign <null> to an implicitly-typed local variable
Дело в том, что значение null неявно приводится к любому ссылочному типу
или значимому типу, допускающему значение null . Соответственно, компилятор
не в состоянии однозначно определить его тип. Однако в третьей операции при-
сваивания я показал, что инициализировать локальную переменную с неявно
заданным типом значением null все-таки можно, если в явном виде указать тип
(в моем примере это тип String ). Впрочем, это не самая полезная возможность, так
как, написав String x = null; , вы получите тот же самый результат.250
Глава 9. Параметры
В четвертом примере в полной мере демонстрируется полезность локальных
переменных неявно заданного типа. Ведь без этой возможности вам бы потребова-
лось с обеих сторон от оператора присваивания писать Dictionary<String , Single> .
Это не просто увеличивает объем набираемого текста, но и заставляет редактировать
код с обеих сторон от оператора присваивания в случае, если вы решите поменять
тип коллекции или любой из типов обобщенных параметров.
В цикле foreach я также воспользовался ключевым словом var , заставив
компилятор автоматически определить тип элементов коллекции. Этот пример
демонстрирует пользу ключевого слова var внутри инструкций foreach , using
и for . Кроме того, оно полезно в процессе экспериментов с кодом. К примеру,
вы инициализируете локальную переменную с неявно заданным типом, взяв за
основу тип возвращаемого методом значения. Но в будущем может появиться не-
обходимость поменять тип возвращаемого значения. В этом случае компилятор
автоматически определит, что тип возвращаемого методом значения изменился,
и изменит тип локальной переменной! К сожалению, остальной код внутри ме-
тода, работающий с этой переменной, может перестать компилироваться — если
этот код обращается к членам в предположении, что переменная принадлежит
к старому типу.
В Microsoft Visual Studio при наведении указателя мыши на ключевое слово
var появляется всплывающая подсказка с названием типа, определяемого компи-
лятором. Функцию неявного задания типа локальных переменных в C# следует