This lesson is not translated yet – the Russian original is below.
Переменная – это именованное место в памяти, куда программа кладёт значение, чтобы вернуться к нему позже. В C# у каждой такой ячейки есть тип, и он задаётся один раз навсегда.
Объявление
int age = 19;
Три части: тип int, имя age, начальное значение 19. Дальше age ведёт себя как число: его
можно складывать, сравнивать, выводить.
Объявить и присвоить можно порознь, но прочитать переменную до первого присваивания нельзя:
int count;
count = 5; // теперь можно читать
Компилятор не подставляет ноль в неприсвоенную переменную, а отказывается собирать программу. Это спасает от целого класса ошибок: значение, которое вы не задавали, никогда не утечёт в вычисления.
Тип меняться не может
Это главное отличие от Python или JavaScript. Тип определяется в объявлении и остаётся навсегда:
int x = 5;
x = "привет"; // ошибка компиляции: строку в int не положить
x = 5
x = "привет" # обычное дело: имя просто указывает на другой объект
Строгая типизация ловит опечатки и путаницу в аргументах до запуска. Плата – многословность: тип приходится называть.
var: тип выводит компилятор
Когда тип очевиден из правой части, его разрешено не повторять:
var age = 19; // int
var name = "Аня"; // string
var prices = new List<double>(); // List<double>
var – не «переменная без типа». Тип есть, просто его вывел компилятор, и изменить его потом
нельзя ровно так же.
Когда писать var, а когда тип – вопрос стиля, и команды договариваются по-разному. Общее правило: если из строки и так видно, что справа, var уместен. Если var result = Process(data); не даёт понять, что получилось, лучше назвать тип.
Базовые типы
Их много, но в работе постоянно встречаются шесть.
| Тип | Что хранит | Размер | Пример |
|---|---|---|---|
int |
целое | 4 байта | 42 |
long |
целое побольше | 8 байт | 9000000000L |
double |
дробное | 8 байт | 3.14 |
decimal |
дробное точное | 16 байт | 19.99m |
bool |
истина или ложь | 1 байт | true |
char |
один символ | 2 байта | 'A' |
string |
текст | переменный | "Привет" |
Три замечания, на которых спотыкаются в первый день:
Дробная часть отделяется точкой. 1.75, а не 1,75 – запятая разделяет аргументы, и
компилятор увидит два числа вместо одного. Запятая появляется только при выводе, и то из-за
настроек локали.
Одинарные и двойные кавычки – разное. 'A' – это char, один символ. "A" – это string
длиной один символ. Перепутать легко, но типы несовместимы.
У литералов тоже есть тип. Число 19.99 компилятор считает double; чтобы получить
decimal, к нему дописывают m: 19.99m. Для long есть суффикс L, для float – f.
Настоящие имена типов
int – это псевдоним. Полное имя типа – System.Int32, и обе записи означают ровно одно:
int a = 5;
Int32 b = 5; // тот же тип, просто длиннее
Псевдонимы существуют для читаемости, и в коде пишут именно их. Но в сообщениях об ошибках и в
документации всплывают полные имена, поэтому связь полезно знать: string – это System.String,
double – System.Double, bool – System.Boolean.
Границы значений
У каждого числового типа есть предел, и он не абстрактный:
Console.WriteLine(int.MaxValue); // 2147483647
Console.WriteLine(int.MinValue); // -2147483648
Два миллиарда кажутся большим запасом ровно до первой задачи, где считают миллисекунды или байты в файле. Что происходит при выходе за границу – тема следующего урока, и происходящее там неприятно.
Константы
Значение, которое не должно меняться, помечают const:
const double Pi = 3.14159;
const int MaxAttempts = 3;
Попытка присвоить константе новое значение – ошибка компиляции. Значение обязано быть известно
на этапе компиляции, поэтому const DateTime Now = DateTime.Now; не соберётся: сейчас – это
разное «сейчас» при каждом запуске.
Число, смысл которого понятен только автору, называют «магическим». if (attempts > 3) через месяц читается как загадка, if (attempts > MaxAttempts) – как предложение. Константа стоит одной строки и экономит чужие полчаса.
Как называть переменные
В C# приняты соглашения, и они соблюдаются повсеместно – чужой код будет написан именно так.
| Что | Как | Пример |
|---|---|---|
| локальная переменная, параметр | camelCase | userName, totalPrice |
| константа, метод, класс, свойство | PascalCase | MaxAttempts, Calculate |
| приватное поле класса | подчёркивание + camelCase | _counter |
Имя обязано начинаться с буквы или подчёркивания и не может совпадать с ключевым словом языка. Кириллица технически разрешена, но так не пишут: имена в коде – латиницей.
Главное правило не про регистр: имя должно объяснять смысл. int d заставляет искать
объявление, int daysLeft – нет. Исключение одно – счётчик цикла i: он живёт три строки, и его
все понимают.