Язык программирования C#9 и платформа .NET5
Часть 218 из 642 Информация о книге
// Операция + со строками.string s1 = "Hello";string s2 = " world!";string s3 = s1 + s2; // s3 теперь имеет значение "Hello World!"Операция
функционирует специфическим образом на основе типа предоставленных данных (в рассматриваемом случае строкового или целочисленного). Когда операция+применяется к числовым типам, в результате выполняется суммирование операндов, а когда к строковым типам — то конкатенация строк.+Язык C# дает возможность строить специальные классы и структуры, которые также уникально реагируют на один и тот же набор базовых лексем (вроде операции
). Хотя не каждая операция C# может быть перегружена, перегрузку допускают многие операции (табл. 11.1).+Перегрузка бинарных операций
Чтобы проиллюстрировать процесс перегрузки бинарных операций, рассмотрим приведенный ниже простой класс
, который определен в новом проекте консольного приложения по имениPoint:OverloadedOpsusing System;namespace OverloadedOps{// Простой будничный класс С#.public class Point{public int X {get; set;}public int Y {get; set;}public Point(int xPos, int yPos){X = xPos;Y = yPos;}public override string ToString()=> $"[{this.X}, {this.Y}]";}}Рассуждая логически, суммирование объектов
имеет смысл. Например, сложение двух переменныхPointдолжно давать новый объектPointс просуммированными значениями свойствPointиX. Конечно, полезно также и вычитать один объектYиз другого. В идеале желательно иметь возможность записи примерно такого кода:Pointusing System;using OverloadedOps;// Сложение и вычитание двух точек?Console.WriteLine("***** Fun with Overloaded Operators *****\n");// Создать две точки.Point ptOne = new Point(100, 100);Point ptTwo = new Point(40, 40);Console.WriteLine("ptOne = {0}", ptOne);Console.WriteLine("ptTwo = {0}", ptTwo);// Сложить две точки, чтобы получить большую точку?Console.WriteLine("ptOne + ptTwo: {0} ", ptOne + ptTwo);// Вычесть одну точку из другой, чтобы получить меньшую?Console.WriteLine("ptOne - ptTwo: {0} ", ptOne - ptTwo);Console.ReadLine();Тем не менее, с существующим видом класса
вы получите ошибки на этапе компиляции, потому что типуPointне известно, как реагировать на операциюPointили+. Для оснащения специального типа способностью уникально реагировать на встроенные операции язык C# предлагает ключевое слово operator, которое может использоваться только в сочетании с ключевым словом-. При перегрузке бинарной операции (такой какstaticи+) вы чаще всего будете передавать два аргумента того же типа, что и класс, определяющий операцию (-в этом примере):Point// Более интеллектуальный тип Point.public class Point{...// Перегруженная операция +.public static Point operator + (Point p1, Point p2)=> new Point(p1.X + p2.X, p1.Y + p2.Y);// Перегруженная операция -.public static Point operator - (Point p1, Point p2)=> new Point(p1.X - p2.X, p1.Y - p2.Y);}Логика, положенная в основу операции
, предусматривает просто возвращение нового объекта+, основанного на сложении соответствующих полей входных параметровPoint. Таким образом, когда вы пишетеPoint, "за кулисами" происходит следующий скрытый вызов статического методаp1 + р2:operator +// Псевдокод: Point рЗ = Point.operator+ (pi, р2)Point p3 = p1 + p2;Аналогично выражение
отображается так:pi - р2// Псевдокод: Point р4 = Point.operator- (pi, р2)Point p4 = p1 - p2;После произведенной модификации типа
программа скомпилируется и появится возможность сложения и вычитания объектовPoint, что подтверждает представленный далее вывод:Point
