Преобразование типов
Вернёмся к коробкам разной формы. Скопировать значение из маленькой коробки в большую можно без вопросов: всё поместится. Из большой в маленькую — только с вашего согласия, ведь часть значения может не влезть и потеряться.
Бывает и задача посложнее. Значение "42" — это текст, а не число, и строку int n = "42"; компилятор не примет. А данные от пользователя или из файла приходят именно текстом. Чтобы с ними считать, текст нужно превратить в число. Разберём все три случая.
Неявное преобразование
Из int в long и в double значение переходит само:
int apples = 12;
long many = apples;
double exact = apples;
Console.WriteLine(many); // 12
Console.WriteLine(exact); // 12Давайте разберём по строкам:
long many = apples;кладётintв коробкуlong: любое значениеintпоместится в неё с запасом.double exact = apples;превращает целое12в дробное12.0.- Обе строки печати выводят
12:doubleс нулевой дробной частью печатается без.0.
Такое преобразование называют неявным: C# выполняет его без вашей команды, ведь любое значение int помещается в long и double целиком. В обратную сторону он сам не переводит. long в int и double в int — ошибка компиляции CS0266: значение может не поместиться.
Явное приведение
Когда вы согласны потерять часть значения, напишите нужный тип в скобках перед значением: (int)price. Это явное приведение:
double price = 3.99;
int whole = (int)price;
Console.WriteLine(whole); // 3
Console.WriteLine((int)-3.99); // -3Разберём, что получилось:
(int)priceотбрасывает дробную часть: из3.99выходит3, а не4.(int)-3.99даёт-3: отбрасывание дроби сдвигает число к нулю, а не вниз.
Здесь аналогия с коробками неточна. Приведение не утрамбовывает значение и не ищет ближайшее целое. Оно отрезает всё, что стоит после точки.
Parse, Convert и ToString
У C# есть и готовые средства перевода — из строки в число, из дробного числа в целое с округлением и из любого значения в строку:
int year = int.Parse("2026");
Console.WriteLine(year); // 2026
Console.WriteLine(Convert.ToInt32(2.5)); // 2
Console.WriteLine(Convert.ToInt32(3.5)); // 4
string text = year.ToString();
Console.WriteLine(text + text); // 20262026int.Parse
int.Parse("2026") читает строку из цифр и возвращает число 2026. Если в строке не целое число, например "4.5", программа остановится с ошибкой — пример в конце урока.
Convert.ToInt32
Convert.ToInt32 переводит в int значения разных типов, в том числе double. В отличие от приведения, он округляет: к ближайшему целому, а ровно посередине — к чётному. Поэтому 2.5 даёт 2, а 3.5 — 4. Такое округление называют банковским.
На собеседовании часто спрашивают, чем (int)x отличается от Convert.ToInt32(x). Ответ: приведение отбрасывает дробную часть, а Convert.ToInt32 округляет до ближайшего целого.
ToString
Обратный путь — ToString(): он превращает значение в строку. year.ToString() даёт текст "2026", поэтому text + text склеивает две строки, а не складывает числа — выходит 20262026.
Частая ошибка
В int.Parse передали строку, в которой, кроме числа, есть слово:
int count = int.Parse("12 apples"); // ✗
Console.WriteLine(count);Unhandled exception. System.FormatException: The input string '12 apples' was not in a correct format.Эта программа компилируется: компилятор не проверяет, что лежит внутри строки. Ошибка случается при запуске. Программа останавливается на строке с int.Parse и печатает отчёт об ошибке. Его первая строка показана выше. До Console.WriteLine дело не доходит.
int.Parse принимает только строку с целым числом: знак в начале и пробелы по краям допустимы, а буквы и точка — нет.
Главное
- Из
intвlongиdoubleзначение переходит неявно, а в обратную сторону нужно явное приведение. (int)3.99даёт3, а(int)-3.99—-3: приведение отбрасывает дробную часть.Convert.ToInt32округляет к ближайшему целому, а ровно посередине — к чётному:2.5даёт2.int.Parseпревращает строку в число и останавливает программу, если в строке не целое число;ToString()делает обратное.