Перейти к содержимому
Теория · Переменные и типы · урок 5 из 8

var и const

Представьте склад, где вы сдаёте вещь кладовщику. Можно заранее сказать: «Нужна коробка для обуви». А можно молча протянуть ботинки — кладовщик и так поймёт, какая коробка подойдёт.

В объявлении int count = 10; форма коробки названа дважды: словом int и самим числом 10. По числу видно, что коробка нужна для целых чисел. C# умеет подобрать тип по значению, как тот кладовщик. Для этого вместо типа пишут var.

var: тип из значения

Ключевое слово var объявляет переменную, а тип для неё компилятор выбирает сам — по значению справа от =. Такой приём называют выводом типа:

C#
var count = 10;
var distance = 2.5;
var city = "Kazan";
var isOpen = true;
Console.WriteLine(count); // 10
Console.WriteLine(distance); // 2.5
Console.WriteLine(city); // Kazan
Console.WriteLine(isOpen); // True
count = 25;
Console.WriteLine(count); // 25

Давайте разберём пример по строкам:

  1. var count = 10; — справа целое число, поэтому count получает тип int.
  2. var distance = 2.5; — число с точкой, тип double.
  3. var city = "Kazan"; — текст в двойных кавычках, тип string.
  4. var isOpen = true; — справа true, тип bool.
  5. count = 25; меняет значение: var объявляет обычную переменную, и её можно перезаписывать.

Тип выбирается при компиляции, ещё до запуска программы. Строка var count = 10; даёт ровно то же, что int count = 10;. В .NET принято писать var, когда тип видно из правой части, и явный тип — когда не видно.

Тип выбирается один раз

Раз count получила тип int, строку в неё уже не положить:

C#
var count = 10;
count = "ten"; // ✗
Console.WriteLine(count);
TEXT
error CS0029: Cannot implicitly convert type 'string' to 'int'

var не делает коробку безразмерной. У count та же форма, что при явном int, и компилятор проверяет её так же строго.

Здесь аналогия со складом заканчивается. Настоящую коробку можно освободить и взять под другую вещь. Тип переменной не меняется никогда: меняется только значение внутри.

На собеседовании часто спрашивают, делает ли var переменную динамически типизированной. В языках с динамической типизацией, например в Python и JavaScript, одна переменная может хранить сначала число, а потом строку. С var так не выйдет: тип фиксируется при компиляции, как если бы его написали явно. Поэтому ответ — нет: переменная с var типизирована статически.

Константы

Ключевое слово const объявляет константу — именованное значение, которое известно уже при компиляции и не меняется, пока программа работает. Это коробка, которую запечатали ещё до запуска:

C#
const int DaysInWeek = 7;
const string Greeting = "Hello";
Console.WriteLine(DaysInWeek); // 7
Console.WriteLine(Greeting); // Hello

Константа даёт имя значению, которое иначе пришлось бы повторять по всей программе. Число 7 в коде может значить что угодно, а имя DaysInWeek сразу говорит, что это число дней в неделе.

Что ещё важно знать о константах:

  • тип указывают явно: const var не скомпилируется (ошибка CS0822);
  • значение должно быть известно при компиляции — например, число, строка, true или false, но не переменная (ошибка CS0133);
  • новое значение константе не присвоить: строка DaysInWeek = 8; не скомпилируется (ошибка CS0131);
  • по соглашению .NET имена констант начинают с заглавной буквы, как и каждое следующее слово в них: DaysInWeek, MaxScore.

Частая ошибка

Переменную объявили через var, а значение решили положить позже:

C#
var total; // ✗
total = 0;
Console.WriteLine(total);
TEXT
error CS0818: Implicitly-typed variables must be initialized

Программа не компилируется. var берёт тип из начального значения, а значения здесь нет — выбирать не из чего. Задайте значение сразу (var total = 0;) или назовите тип явно (int total;).

Главное

  • var берёт тип из начального значения при компиляции: var count = 10; — то же, что int count = 10;.
  • У переменной, объявленной через var, тип не меняется, а значение меняется, как у любой переменной.
  • Объявление с var без начального значения не компилируется: выбирать тип не из чего.
  • const объявляет константу: её значение известно при компиляции и не меняется.