Полное руководство по языку программирования С# 14 и платформе .NET 10 / Основы программирования на C#

Преобразования базовых типов данных

Начальный ⏱ 5 мин чтения 👁 2 🕓 обновлено 11.08.2026

При рассмотрении типов данных указывалось, какие значения может иметь тот или иной тип и сколько байт памяти он может занимать. В прошлой теме были расмотрены арифметические операции. Теперь применим операцию сложения к данным разных типов:


byte a = 4;
int b = a + 70;

Результатом операции вполне справедливо является число 74, как и ожидается.

Но теперь попробуем применить сложение к двум объектам типа byte:


byte a = 4;
byte b = a + 70;  // ошибка

Здесь поменялся только тип переменной, которая получает результат сложения - с int на byte. Однако при попытке скомпилировать программу мы получим ошибку на этапе компиляции. И если мы работаем в Visual Studio, среда подчеркнет вторую строку красной волнистой линией, указывая, что в ней ошибка.

При операциях мы должны учитывать диапазон значений, которые может хранить тот или иной тип. Но в данном случае число 74, которое мы ожидаем получить, вполне укладывается в диапазон значений типа byte, тем не менее мы получаем ошибку.

Дело в том, что операция сложения (да и вычитания) возвращает значение типа int, если в операции участвуют целочисленные типы данных с разрядностью меньше или равно int (то есть типы byte, short, int). Поэтому результатом операции a + 70 будет объект, который имеет длину в памяти 4 байта. Затем этот объект мы пытаемся присвоить переменной b, которая имеет тип byte и в памяти занимает 1 байт.

И чтобы выйти из этой ситуации, необходимо применить операцию преобразования типов. Операция преобразования типов предполагает указание в скобках того типа, к которому надо преобразовать значение:


(тип_данных_в_который_надо_преобразовать)значение_для_преобразования;

Так, изменим предыдущий пример, применив операцию преобразования типов:


byte a = 4;
byte b = (byte)(a + 70);

Сужающие и расширяющие преобразования

Преобразования могут быть сужающие (narrowing) и расширяющие (widening). Расширяющие преобразования расширяют размер объекта в памяти. Например:


byte a = 4;				// 0000100
ushort b = a;	// 000000000000100

В данном случае переменной типа ushort присваивается значение типа byte. Тип byte занимает 1 байт (8 бит), и значение переменной a в двоичном виде можно представить как:

00000100

Значение типа ushort занимает 2 байта (16 бит). И при присвоении переменной b значение переменной a расширяется до 2 байт

0000000000000100

То есть значение, которое занимает 8 бит, расширяется до 16 бит.

Сужающие преобразования, наоборот, сужают значение до типа меньшей разядности. Во втором листинге статьи мы как раз имели дело с сужающими преобразованиями:


ushort a = 4;
byte b = (byte) a;

Здесь переменной b, которая занимает 8 бит, присваивается значение ushort, которое занимает 16 бит. То есть из 0000000000000100 получаем 00000100. Таким образом, значение сужается с 16 бит (2 байт) до 8 бит (1 байт).

Явные и неявные преобразования

Неявные преобразования

В случае с расширяющими преобразованиями компилятор за нас выполнял все преобразования данных, то есть преобразования были неявными (implicit conversion). Такие преобразования не вызывают каких-то затруднений. Тем не менее стоит сказать пару слов об общей механике подобных преобразований.

Если производится преобразование от безнакового типа меньшей разрядности к безнаковому типу большой разрядности, то добавляются дополнительные биты, которые имеют значени 0. Это называется дополнение нулями или zero extension.


byte a = 4;				// 0000100
ushort b = a;	// 000000000000100

Если производится преобразование к знаковому типу, то битовое представление дополняется нулями, если число положительное, и единицами, если число отрицательное. Последний разряд числа содержит знаковый бит - 0 для положительных и 1 для отрицательных чисел. При расширении в добавленные разряды компируется знаковый бит.

Рассмотрим преобразование положительного числа:


sbyte a = 4;			// 0000100
short b = a;	// 000000000000100

Преобразование отрицательного числа:


sbyte a = -4;			// 1111100
short b = a;	// 111111111111100

Явные преобразования

При явных преобразованиях (explicit conversion) мы сами должны применить операцию преобразования (операция ()). Суть операции преобразования типов состоит в том, что перед значением указывается в скобках тип, к которому надо привести данное значение:


int a = 4;
int b = 6;
byte c = (byte)(a+b);

Расширяющие преобразования от типа с меньшей разрядностью к типу с большей разрядностью компилятор проводит неявно. Это могут быть следующие цепочки преобразований:

byte -> short -> int -> long -> decimal

int -> double

short -> float -> double

char -> int

Все безопасные автоматические преобразования можно описать следующей таблицей:

Тип

В какие типы безопасно преобразуется

byte

short, ushort, int, uint, long, ulong, float, double, decimal

sbyte

short, int, long, float, double, decimal

short

int, long, float, double, decimal

ushort

int, uint, long, ulong, float, double, decimal

int

long, float, double, decimal

uint

long, ulong, float, double, decimal

long

float, double, decimal

ulong

float, double, decimal

float

double

char

ushort, int, uint, long, ulong, float, double, decimal

В остальных случаях следует использовать явные преобразования типов.

Также следует отметить, что несмотря на то, что и double, и decimal могут хранить дробные данные, а decimal имеет большую разрядность, чем double, но все равно значение double нужно явно приводить к типу decimal:


double a = 4.0;
decimal b = (decimal)a;

Потеря точности данных

Рассмотрим другую ситуацию, что будет, например, в следующем случае:


int a = 33;
int b = 600;
byte c = (byte)(a+b);
Console.WriteLine(c);   // 121

Результатом будет число 121, так число 633 не попадает в допустимый диапазон для типа byte, и старшие биты будут усекаться. В итоге получится число 121. Поэтому при преобразованиях надо это учитывать. И мы в данном случае можем либо взять такие числа a и b, которые в сумме дадут число не больше 255, либо мы можем выбрать вместо byte другой тип данных, например, int.

Дополнительные материалы

Проверь себя

📋 Тест по теме «Преобразования базовых типов данных» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

_____ a = 4;
int b = a + 70;
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

byte a = _____;
byte b = a + 70;  // ошибка
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

_____ a = 4;
byte b = (byte)(a + 70);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

byte a = 4;				// 0000100
ushort b = a;	// _____
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

byte a = _____;
int b = a + _____;
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

_____ a = 4;
byte b = a + _____;  // ошибка
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

int b = 6;
byte c = (byte)(a+b);
int a = 4;
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Преобразования базовых типов данных»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Преобразования базовых типов данных», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

byte a = 4;
int b = a + 70;
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Преобразования базовых типов данных»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

byte a = 4;
byte b = a + 70;  // ошибка
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Преобразования базовых типов данных»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Преобразования базовых типов данных»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Преобразования базовых типов данных». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.