Содержание
При работе с различными типами данных, нам часто приходится преобразовывать один тип данных в другой, чтобы выполнить какие-либо операции. Преобразование базовых типов данных в C# – это, наряду с темой о работе циклов, является одной из основных тем изучения языка программирования C#. Незнание того как преобразуются данные в C# или неумение использовать преобразование данных может не только сузить ваши возможности по разработке даже самых простых программ, но и привести к критическим ошибкам в работе приложений.
Преобразование базовых типов данных в C#
Мы уже знаем, что C# является типизированным языком программирования и каждая переменная в программе должна иметь имя и тип. При этом, мы не можем изменять тип переменной или присваивать ей значение другого типа. Например,
int i = 0; //инициализировали целочисленную переменную i = "s"; //нельзя присвоить целочисленной переменной строку
В Visual Studio мы получим ошибку:
Что значит “неявно”? А можно ли тогда преобразовать строку в число явно? Эти и другие вопросы вполне возможно возникают у каждого новичка в C#. Поэтому мы сегодня и будем детально разбираться с механизмами преобразования базовых типов данных в C#, чтобы в дальнейшем мы могли решать более сложные задачи, чем задачи вывода “Hello, World!” и перебора символов строки в консоли.
Виды преобразований типов данных в C#
В C# преобразования типов данных условно можно разделить на два вида — это неявные преобразования и явные преобразования.
Неявные преобразования в C#
Неявные преобразования в C# – это преобразования одного типа данных в другой, которые осуществляются в C# без нашего прямого указания. Для того, чтобы произошло неявное преобразование специальный синтаксис не требуется и такое преобразование всегда выполняется успешно.
Неявные преобразования могут выполняться, например, из меньших в большие целочисленные типы. Рассмотрим следующий код:
byte a = 255; int b = a; a = b;
здесь переменные a и b имеют разные типы данных. И без неявного преобразования мы должны были бы получить ошибку, как показано выше. Но такой код вполне успешно скомпилируется и запустится. Вспомним информацию по типам данных в C#:
| Псевдоним типа в C# | Описание | Размер, байт |
|---|---|---|
byte |
целое число в диапазоне от 0 до 255 | 1 |
int |
целое число в диапазоне от -2 147 483 648 до 2 147 483 647 | 4 |
Обратите внимание на размеры типов данных: int– это больший целочисленный тип, чем byteпоэтому срабатывает неявное преобразование и значение переменной aпреобразуется в intи присваивается переменной. И, как видите, здесь нет противоречий с ранее изученным материалом – переменной присваивается значение того же типа, что и сама переменная. В C# такое преобразование также называется расширяющим — мы расширяем размер объекта (переменной) в памяти.
Для каких числовых типов данных используется неявное преобразование в C#?
Ниже представлена таблица, в которой представлены числовые типы данных для которых может применяться неявное преобразование в C#
| Тип | В какие типы данных может неявно преобразовываться |
sbyte |
short, int, long, float, double, decimal или nint |
byte |
short, ushort, int, uint, long, ulong, float, double, decimal, nint или nuint |
short |
int, long, float, double или decimal либо nint |
ushort |
int, uint, long, ulong, float, double или decimal, nint или nuint |
int |
long, float, double или decimal, nint |
uint |
long, ulong, float, double или decimal либо nuint |
long |
float, double или decimal |
ulong |
float, double или decimal |
float |
double |
nint |
long, float, double или decimal |
nuint |
ulong, float, double или decimal |
Обратите внимание – любой целочисленный тип данных свободно преобразуется в вещественный. Например, intв doubleили byteв floatи так далее. При этом не поддерживается неявное преобразования:
- в типы
byteиsbyte - из типов
doubleиdecimal - между типом
decimalи типамиfloatилиdouble.
Явные преобразования в C#
Явные преобразования также называют приведением типов. Для явных преобразований требуется выражение приведения. Приведение требуется, если в ходе преобразования данные могут быть утрачены или преобразование может завершиться сбоем по другим причинам. Типичными примерами являются числовое преобразование в тип с меньшей точностью или меньшим диапазоном допустимых значений.
Рассмотрим следующий пример:
byte a = 10; a = a + 100;
По умолчанию, результат сложения двух целых чисел в C# имеет тип int, а переменная aимеет тип byte, который меньше по размеру, чем int. Таким образом, чтобы присвоить переменной новое значение, необходимо произвести преобразование типа результата вычисления в byte, но так как неявное преобразование производится из типов с большим размером в типы с меньшим размером, то мы получим снова ошибку:
В приведенном примере нет никакого риска потери данных и мы явно видим, что значение переменной не выйдет за допустимый диапазон значений для типа byte. Чтобы Visual Studio перестала выдавать нам ошибку преобразования, перепишем этот пример следующим образом:
byte a = 10; a = (byte)(a + 100);
здесь мы во второй строке использовали выражение приведения. То есть, чтобы произвести явное приведение мы в круглых скобках указываем тип данных к которому необходимо привести какое-либо значение или переменную. В нашем случае мы производим явное преобразование всего выражения a+100, поэтому мы все выражение также заключили в круглые скобки.
Выше было сказано про потерю точности и потерю данных. Когда при явном преобразовании мы можем потерять данные? Самый очевидный пример – когда значение переменной выйдет за допустимый диапазон значения типа данных. Перепишем наш пример следующим образом:
byte a = 10; a = (byte)(a + 400); Console.WriteLine(a);
Вопреки нашим ожиданиям увидеть ответ 410, в консоли мы увидим:

Откуда взялось число 54? Дело в том, что тип int — имеет разрядность 4 байта (32 бита), а тип byte — всего 1 байт (8 бит), поэтому при преобразовании компилятор отбрасывает старшие биты числа, представленного в двоичной системе счисления и, в результате число: 00000100110110 (410 в десятичной системе) превратится в 00110110 (154 в десятичной системе).
Приведенный пример наглядно демонстрирует потерю данных при явном преобразовании числовых данных.
Преобразование данных с помощью класса Convert
С явным и неявным преобразованием числовых данных разобрались. Но как нам быть в случае, если потребуется перевести, скажем, строку в число (string -> int)? При попытке выполнить вот такой код:
int a; string b = "123"; a = (int)b;
Мы получим ошибку:
То есть ни явно, ни неявно мы такое преобразование сделать не можем. В этом случае нам пригодится специальный класс Convert, которые производит конвертацию из одного типа данных в другой. Для того, чтобы конвертировать данные из одного типа в другой, используются следующие методы класса Convert
ToBoolean(value) ToByte(value) ToChar(value) ToDateTime(value) ToDecimal(value) ToDouble(value) ToInt16(value) ToInt32(value) ToInt64(value) ToSByte(value) ToSingle(value) ToUInt16(value) ToUInt32(value) ToUInt64(value)
value– это значение базового типа, которое необходимо преобразовать в другой базовый тип данных. Выше перечислены далеко не все методы этого класса, но для нас пока хватит и этого списка. Например, применим этот класс для работы в консольном приложении:
Console.WriteLine("Введите целое число от 0 до 10: ");
int number = Convert.ToInt32(Console.ReadLine());
if ((number > 10) || (number < 0))
Console.WriteLine("Введенное число выходит за заданный диапазон");
else
Console.WriteLine($"Число {number} подходит");
Console.ReadKey();
здесь мы используем метод ToInt32(value), чтобы преобразовать введенную пользователем строку в целое число типа intи, в зависимости от полученного значения, выводим пользователю сообщение.
В дальнейшем, при изучении C#, мы будем часто использовать класс Convertдля преобразования данных.
Преобразование данных с помощью методов типов
Практически все базовые типы данных, такие как int, double, floatи ряд других типов данных, с которыми мы ещё познакомимся, позволяют воспользоваться своими методами вида Parse()и TryParse()для получения данных из строк. Например,
int i = int.Parse("1");
В результате, переменная i получит значение 1 из строки. Методы TryParse()возвращают значение trueв том случае, если преобразование прошло успешно, что позволяет использовать эти методы в условных выражениях. Например,
int i;
if (int.TryParse("1", out i))
Console.WriteLine("Успешное преобразование string в int");
else
Console.WriteLine("Ошибка преобразования string в int");
здесь, в зависимости от результата выполнения метода TryParse()мы увидим в консоли одно из двух сообщений. Конкретно в нашем примере, преобразование произойдет успешно.
Подведем итог
Преобразование базовых типов данных в C# может быть явным и неявным. Неявное преобразование производится автоматически и не требует от нас никаких действий, так как в этом случае нет риска потери данных или точности вычислений. В свою очередь, явное преобразование требуется в том случае, если есть риски потери данных или точности. Для явного преобразования нам необходимо указать выражение приведения. В случае, если нам необходимо конвертировать значения, типы которых невозможно преобразовать, используя явное или неявное преобразование (например перевести число в строку), то в этом случае, мы можем воспользоваться классом Convert, который преобразуется одни базовые типы данных в другие.
Домашнее задание №14
Домашнее задание по C#: пользователь вводит с клавиатуры сумму вклада в рублях (с точностью до копейки) и процентную ставку (целое число от 5 до 25) в процентах годовых. Рассчитать срок в месяцах, через который сумма на счёте превысит 15 000 рублей. В случае ошибки ввода данных пользователем программа должна сообщать об этом до тех пор пока ошибка не будет ликвидирована. Ошибками ввода вместо чисел других символов, например, букв русского алфавита, можно пренебречь – вводится должны только цифры и знак “запятая” для разделения целой и дробной части числа