Треки
/
C#
C#
/
Салабус
/
Перевантаження операторів
Пе

Перевантаження операторів у C#

2 вправи

Про концепцію Перевантаження операторів

Головні арифметичні оператори та оператори порівняння можна пристосувати для використання у власних класах і структурах. Це називається перевантаженням операторів.

У цій статті ґрунтовно розглянуто синтаксис, а також те, які оператори можна перевантажувати, а які ні.

Більшість операторів мають такий вигляд:

static <return type> operaator <operator symbols>(<parameters>);

Оператори приведення мають такий вигляд:

static (explicit|implicit) operator <cast-to-type>(<cast-from-type> <parameter name>);

Оператори поводяться так само, як статичні методи.

  • Символ оператора замінює ідентифікатор методу, і він має параметри та тип, що повертається. Правила типів для параметрів і типу, що повертається, узгоджуються з інтуїцією, і можна покластися на компілятор, який дасть докладні підказки.
  • Для бінарних операцій перший параметр приймає лівий аргумент операції.
  • Оператори мають сигнатуру, що складається з двох параметрів (для бінарних операцій) і типу, що повертається, або з одного параметра й типу, що повертається для унарних операторів.
  • Для бінарних операторів один із типів параметрів має бути типом класу, що оголошує оператор.
  • У разі перетворень типів або параметр, або тип, що повертається, має бути типом класу, що оголошує оператор.
  • Для операторів інкременту й декременту і параметр, і тип, що повертається, мають бути типом класу, що оголошує оператор.

Приклади синтаксису:

struct Point
{
    decimal x;
    decimal y;

    public static bool operator ==(Point pt, Point ptOther)
    {
        return pt.x == ptOther.x && pt.y == ptOther.y;
    }

    public static bool operator !=(Point pt, Point ptOther)
    {
        return !(pt == ptOther);
    }

    public static Point operator *(Point pt, decimal scale)
    {
        var ptNew = new Point();
        ptNew.x = pt.x * scale;
        ptNew.y = pt.y * scale;
        return ptNew;
    }

    public static implicit operator Point((decimal x, decimal y) xy)
    {
        var pt = new Point();
        pt.x = xy.x;
        pt.y = xy.y;
        return pt;
    }

    public static explicit operator (decimal x, decimal y)(Point pt)
    {
        return (pt.x, pt.y);
    }
}

Часто продуктивно реалізувати метод Equals() і викликати його з оператора ==. Так само для порівнянь можна реалізувати інтерфейс IComparable. В обох випадках можна вбити двох зайців одним каменем, щоправда, трохи більшим.

Зауважмо, що не можна створювати оператори із символів, які не належать до стандартного набору операторів. Можна використовувати лише наявні символи для тих операцій, які, за документацією, можна перевантажувати. Оператори, які можна перевантажувати, перелічено тут.

Зауважмо, що порядок параметрів важливий, коли вони різняться за типом. У наведеному вище прикладі коду pt * 10m є коректним виразом, а 10m * pt не скомпілюється.

Довідка

У цій документації з перевантаження операторів докладно описано синтаксис.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Перевантаження операторів

Практика заблокована

Розблокуйте ще 1 вправу, щоб практикувати концепцію Перевантаження операторів