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

Перегрузка операций преобразования типов

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

В прошлой теме была рассмотрена тема перегрузки операторов. И с этой темой тесно связана тема перегрузки операторов преобразования типов.

Ранее мы рассматривали явные и неявные преобразования примитивных типов. Например:


int x = 50;
byte y = (byte)x; // явное преобразование от int к byte
int z = y;  // неявное преобразование от byte к int

И было бы не плохо иметь возможность определять логику преобразования одних типов в другие. И с помощью перегрузки операторов мы можем это делать. Для этого в классе определяется метод следующей формы:


public static implicit|explicit operator Тип_в_который_надо_преобразовать(исходный_тип param)
{
	// логика преобразования
}

После модификаторов public static идет ключевое слово explicit (если преобразование явное, то есть нужна операция приведения типов) или implicit (если преобразование неявное). Затем идет ключевое слово operator и далее возвращаемый тип, в который надо преобразовать объект. В скобках в качестве параметра передается объект, который надо преобразовать.

Например, пусть у нас есть следующий класс Counter, который представляет счетчик-секундомер и который хранит количество секунд в свойстве Seconds:


class Counter
{
	public int Seconds { get; set; }

	public static implicit operator Counter(int x)
	{
		return new Counter { Seconds = x };
	}
	public static explicit operator int(Counter counter)
	{
		return counter.Seconds;
	}
}

Первый оператор преобразует число - объект типа int к типу Counter. Его логика проста - создается новый объект Counter, у которого устанавливается свойство Seconds.

Второй оператор преобразует объект Counter к типу int, то есть получает из Counter число.

Примение операторов преобразования в программе:


Counter counter1 = new Counter { Seconds = 23 };

int x = (int)counter1;
Console.WriteLine(x);   // 23

Counter counter2 = x;
Console.WriteLine(counter2.Seconds);  // 23

Поскольку операция преобразования из Counter в int определена с ключевым словом explicit, то есть как явное преобразование, то в этом случае необходимо применить операцию приведения типов:

int x = (int)counter1;

В случае с операцией преобразования от int к Counter ничего подобного делать не надо, поскольку данная операция определена с ключевым словом implicit, то есть как неявная. Какие операции преобразования делать явными, а какие неявные, в данном случае не столь важно, это решает разработчик по своему усмотрению.

Следует учитывать, что оператор преобразования типов должен преобразовывать из типа или в тип, в котором этот оператор определен. То есть оператор преобразования, определенный в типе Counter, должен либо принимать в качестве параметра объект типа Counter, либо возвращать объект типа Counter.

Рассмотрим также более сложные преобразования, к примеру, из одного составного типа в другой составной тип. Допустим, у нас есть еще класс Timer:


class Timer
{
	public int Hours { get; set; }
	public int Minutes { get; set; }	
	public int Seconds { get; set; }
}
class Counter
{
	public int Seconds { get; set; }

	public static implicit operator Counter(int x)
	{
		return new Counter { Seconds = x };
	}
	public static explicit operator int(Counter counter)
	{
		return counter.Seconds;
	}
	public static explicit operator Counter(Timer timer)
	{
		int h = timer.Hours * 3600;
		int m = timer.Minutes * 60;
		return new Counter { Seconds = h + m + timer.Seconds };
	}
	public static implicit operator Timer(Counter counter)
	{
		int h = counter.Seconds / 3600;
		int m = (counter.Seconds % 3600) / 60;
		int s = counter.Seconds % 60;
		return new Timer { Hours = h, Minutes = m, Seconds = s };
	}
}

Класс Timer представляет условный таймер, который хранит часы, минуты и секунды. Класс Counter представляет условный счетчик-секундомер, который хранит количество секунд. Исходя из этого мы можем определить некоторую логику преобразования из одного типа к другому, то есть получение из секунд в объекте Counter часов, минут и секунд в объекте Timer. Например, 3675 секунд по сути это 1 час, 1 минута и 15 секунд

Применение операций преобразования:


Counter counter1 = new Counter { Seconds = 115 };

Timer timer = counter1;
Console.WriteLine($"{timer.Hours}:{timer.Minutes}:{timer.Seconds}"); // 0:1:55

Counter counter2 = (Counter)timer;
Console.WriteLine(counter2.Seconds);  //115
Дополнительные материалы

Проверь себя

📋 Тест по теме «Перегрузка операций преобразования типов» Тест по теме

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

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

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

int x = _____;
byte y = (byte)x; // явное преобразование от int к byte
int z = y;  // неявное преобразование от byte к int
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

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

public static implicit|_____ operator Тип_в_который_надо_преобразовать(исходный_тип param)
{
	// логика преобразования
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

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

class Counter
{
	public int Seconds { _____; set; }

	public static implicit operator Counter(int x)
	{
		return new Counter { Seconds = x };
	}
	public static explicit operator int(Counter counter)
	{
		return counter.Seconds;
	}
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

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

_____ counter1 = new Counter { Seconds = 23 };

int x = (int)counter1;
Console.WriteLine(x);   // 23

Counter counter2 = x;
Console.WriteLine(counter2.Seconds);  // 23
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

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

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

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

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

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

public static implicit|explicit _____ Тип_в_который_надо_преобразовать(исходный_тип _____)
{
	// логика преобразования
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

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

byte y = (byte)x; // явное преобразование от int к byte
int z = y;  // неявное преобразование от byte к int
int x = 50;
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Перегрузка операций преобразования типов»
+30 XP

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

int x = 50;
byte y = (byte)x; // явное преобразование от int к byte
int z = y;  // неявное преобразование от byte к int
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Перегрузка операций преобразования типов»
+30 XP

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

public static implicit|explicit operator Тип_в_который_надо_преобразовать(исходный_тип param)
{
	// логика преобразования
}
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Перегрузка операций преобразования типов»
+50 XP

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

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

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

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

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

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