Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

using 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
, что подтверждает представленный далее вывод:

***** Fun with Overloaded Operators *****

ptOne = [100, 100]

ptTwo = [40, 40]

ptOne + ptTwo: [140, 140]

ptOne - ptTwo: [60, 60]

При перегрузке бинарной операции передавать ей два параметра того же самого типа не обязательно. Если это имеет смысл, тогда один из аргументов может относиться к другому типу. Например, ниже показана перегруженная операция

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

public class Point

{

...

public static Point operator + (Point p1, int change)

=> new Point(p1.X + change, p1.Y + change);

public static Point operator + (int change, Point p1)

=> new Point(p1.X + change, p1.Y + change);

}

Обратите

внимание, что если вы хотите передавать аргументы в любом порядке, то потребуется реализовать обе версии метода (т.е. нельзя просто определить один из методов и рассчитывать, что компилятор автоматически будет поддерживать другой). Теперь новые версии операции
+
можно применять следующим образом:

// Выводит [110, 110].

Point biggerPoint = ptOne + 10;

Console.WriteLine("ptOne + 10 = {0}", biggerPoint);

// Выводит [120, 120].

Console.WriteLine("10 + biggerPoint = {0}", 10 + biggerPoint);

Console.WriteLine;

А как насчет операций += и -=?

Если до перехода на C# вы имели дело с языком C++, тогда вас может удивить отсутствие возможности перегрузки операций сокращенного присваивания (

+=
,
– +
и т.д.). Не беспокойтесь. В C# операции сокращенного присваивания автоматически эмулируются в случае перегрузки связанных бинарных операций. Таким образом, если в классе
Point
уже перегружены операции
+
и
, то можно написать приведенный далее код:

// Перегрузка бинарных операций автоматически обеспечивает

// перегрузку сокращенных операций.

...

// Автоматически перегруженная операция +=

Point ptThree = new Point(90, 5);

Console.WriteLine("ptThree = {0}", ptThree);

Console.WriteLine("ptThree += ptTwo: {0}", ptThree += ptTwo);

// Автоматически перегруженная операция -=

Point ptFour = new Point(0, 500);

Console.WriteLine("ptFour = {0}", ptFour);

Console.WriteLine("ptFour -= ptThree: {0}", ptFour -= ptThree);

Console.ReadLine;

Перегрузка унарных операций

В языке C# также разрешено перегружать унарные операции, такие как

++
и
– -
. При перегрузке унарной операции также должно использоваться ключевое слово
static
с ключевым словом
operator
, но в этом случае просто передается единственный параметр того же типа, что и класс или структура, где операция определена. Например, дополните реализацию
Point
следующими перегруженными операциями:

public class Point

{

...

// Добавить 1 к значениям X/Y входного объекта Point.

public static Point operator ++(Point p1)

=> new Point(p1.X+1, p1.Y+1);

// Вычесть 1 из значений X/Y входного объекта Point.

public static Point operator --(Point p1)

=> new Point(p1.X-1, p1.Y-1);

Поделиться с друзьями: