В языке программирования С# процесс, который позволяет определять назначение оператора по отношению к создаваемому классу, называется перегрузка операторов. Он расширяет область применения оператора в классе. Поведение оператора можно менять и контролировать.
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Перегрузка операций в С# похожа на переопределение методов. В языке С# в зависимости от типа оператора объявляется оно двумя способами.
// перегрузка унарного оператора public static тип operator primer(тип_параметра операнд) { // запросы } // перегрузка бинарного оператора public static тип operator primer (тип_параметра1 операнд1, тип_параметра1 операнд2) { // запросы }
Метод объявляется модификаторами public и static. Оператор, который перегружается должен быть одного типа с операндами.
Во время перегрузки оператора его функция и свойство не теряется, он только выполняет еще одну операцию. К примеру, оператор + используется для работы со списком при этом его назначение к сложению целых чисел не меняется. Когда оператор + используется со строковыми данными, выполняется перегрузка оператора со стороны класса String.
В С# существует операторы «+», «-», «!», «==», «!=» и другие, которые предназначены для работы с типами данных.
Так как в языке программирования С# используются готовые алгоритмы базовых операций, в некоторых моментах важна перегрузка операторов. Например, когда используем оператор + для целых чисел он возвращает сумму чисел, а если использовать его для строковых типов данных тогда выполняется объединение двух строк.
string a = "Сергей "; string b = "Сергеев"; string c = a + b; //результат "Сергей Сергеев"
Перегрузка операторов позволяет добавлять удобный синтаксис для работы с классом в среду программирования. Это возможность одна из сильных сторон объектно-ориентированного языка программирования С#.
Когда в классе присутствует перегруженный оператор, компилятор сначала выполняет поведение определенное пользователем, если не определено, то осуществляется стандартная реализация.
Перегрузка операторов С# делает код красивее. Мы задаем, редактируем, или сами можем придумывать поведение определенного нами класса. Используя унарные, бинарные операторы, операторы сравнения и логические операторы мы задаем определенное действие компилятору.
Например, есть класс «точки» с координатами х и у. Два целых числа, объединенные одним классом. Мы можем сложить эти две точки. Даже если компилятор умный, система не в состоянии понять какое сложение точек выполнить. Поэтому нужно перегружать оператор, чтобы объяснить компилятору, как системе себя вести и какое действие выполнить. Возможно системе нужно сложить между собой все х или же сложить все y. Компилятор может выполнить банальное сложение двух заданных точек, но, чтобы их выполнить, нужно указать поведение: например, когда нужно решать по формуле, для этого и служит перегрузка операторов. При ней пользователь С# задает правильное поведение, которое ожидается от класса.
class MyPoint { int х, у,z// три координаты public MyPoint() { х = у = z = 0; } // Перегрузить бинарный оператор +. public static MyPoint operator +(MyPoint op1, MyPoint op2) { MyPoint result = new MyPoint(); /* Сложить координаты двух точек и возвратить результат. */ result.х = op1.x + ор2.х; // Эти операторы выполняют result.у = op1.y + ор2.у; // целочисленное сложение, result.z = op1.z + op2.z; // сохраняя свое исходное назначение. return result; } // Перегрузить бинарный оператор -. public static MyPoint1 operator -(MyPoint1 op1, MyPoint1 op2) { MyPoint1 result = new MyPoint1(); /* Обратите внимание на порядок следования операндов: op1 — левый операнд, а ор2 — правый операнд. */ result.х = op1.x - ор2.х; // Эти операторы result.у = op1.y - ор2.у; // выполняют целочисленное result.z = op1.z - op2.z; // вычитание return result; } // Вывести координаты X, Y, Z. public void Show() { Console.WriteLine(x + ", " + у + ", " + z); } }
Когда оператор перегружается, выполняет заданные поведение. Но его первоначальное назначение не меняется.
Перегружаемые операторы
Эти операторы можно перегрузить:
- Унарные операции +, -, !, ++, — true, false;
- Бинарные операции +, -, *, /, %, &, |, ,<<, >>;
- Операции сравнения должны быть перегружены парами ==, !=,<, >,<=, >=.
Данный код перегружает операцию сравнения. Выбирая значение из операндов, компилятор выполняет сравнение и возвращает истину или ложь.
// Перегрузить оператор >. public static bool operator >(dot op1, dot op2) { if(op1.val > op2.val) return true; else return false; } // Перегрузить оператор <. public static bool operator <( dot op1, dot op2) { if(op1.val < op2.val) return true; else return false; }
Еще один пример для перегрузки операторов ==, -, *= приведен ниже. В качестве класса выберем «квадратное уравнение» с коэффициентами.
class KvadratUravn { public KvadratUravn ():this(0, 0, 0) { } public KvadratUravn (double a_, double b_, double c_) { a=a_; b=b_; c=c_; } public double A { get { return a; } set { a = value; } } public double B { get { return b; } set { b = value; } } public double C { get { return c; } set { c = value; } } public static bool operator ==( KvadratUravn raz, KvadratUravn dva) { return raz.a == dva.a && raz.b == dva.b && raz.c == dva.c; } public static bool operator !=( KvadratUravn raz, KvadratUravn dva) { return raz.a != dva.a && raz.b != dva.b && raz.c != dva.c; } public static KvadratUravn operator *( KvadratUravn raz, double dva) { return new KvadratUravn (raz.a * dva, raz.b * dva, raz.c * dva); } public static KvadratUravn operator -( KvadratUravn raz, double dva) { return new KvadratUravn (raz.a - dva, raz.b - dva, raz.c - dva); } public override string ToString() { return string.Format("{0}, {1}, {2}", a, b, c); } private double a; private double b; private double c; }; class Program { static void Main(string[] args) { KvadratUravn expr = new KvadratUravn (1, 2, 3); Console.WriteLine(expr.ToString()); expr *= 5; Console.WriteLine(expr.ToString()); expr -= 10; Console.WriteLine(expr.ToString()); } }
В следующем фрагменте кода программы приведен пример перегрузки логических операторов !, & и | для объектов класса Dot. Если один из точек координаты не равно нулю тогда программе покажет истину, а если все координаты равны нулю, тогда программа выдает значение ложь.
// Класс для хранения координат. class dot { int х, у, z; // трехмерные координаты public dot () { х = у = z = 0; } public static bool operator |(dot op1, dot op2) { if( ((op1.x != 0) || (op1.у != 0) || (op1.z != 0)) | ((op2.x != 0) || (op2.у != 0) || (op2.z != 0)) ) return true; else return false; } // Перегрузить логический оператор &. public static bool operator &(dot op1, dot op2) { if( ((op1.x != 0) && (op1.у != 0) && (op1.z != 0)) & ((op2.x != 0) && (op2.y != 0) && (op2.z != 0)) ) return true; else return false; } // Перегрузить логический оператор !. public static bool operator !(dot op) { if((op.x != 0) || (op.y != 0) || (op.z != 0)) return false; else return true; } // Вывести координаты X, Y, Z. public void Show() { Console.WriteLine(x + ", " + у + ", " + z); } }
Перегрузка операторов C# заключение
Важно помнить, что на перегрузку операторов есть ограничения. Нельзя использовать оператор присваивания =. Кроме них есть операторы, которые в языке С# еще не определены. Так же, нельзя изменить количество операндов. Для бинарных операторов нельзя задавать три аргумента. Поскольку в его синтаксисе указан только два аргумента.
Чтобы создать легкий интерфейс, важно использовать перегрузки операторов. К тому же, учитывая их, вы упрощаете набранный код программы. Данное действие над операторами интересно тем, что пользователь сможет внедрить в программу свои правила и требования, контролируя функции операторов.
Также рекомендую прочитать статью Override C# | Переопределение методов C#. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.