Поделиться через


Операторы - и -= — вычитание (минус)

Встроенные типы делегатов и целочисленные и числовые типы с плавающей запятой поддерживают - и -= операторы.

Справочные документы по языку C# описывают последнюю выпущенную версию языка C#. Она также содержит начальную документацию по функциям в общедоступных предварительных версиях для предстоящего языкового выпуска.

Документация определяет любую функцию, впервые представленную в последних трех версиях языка или в текущих общедоступных предварительных версиях.

Подсказка

Чтобы узнать, когда функция впервые появилась в C#, ознакомьтесь со статьей об истории версий языка C#.

Для получения информации об арифметическом - операторе, см. разделы унарных операторов плюс и минус и оператора вычитания - в статье об арифметических операторах.

Удаление делегата

Для операндов одного типа - делегата оператор возвращает экземпляр делегата, вычисляемый следующим образом:

  • Если оба операнда не null являются, а список вызовов правой операнда является правильным смежным вложенным списком списка вызовов левого операнда, результатом операции является новый список вызовов, который вы получаете, удалив записи правого операнда из списка вызовов левого операнда. Если список операнда справа совпадает с несколькими смежными вложенными списками в списке операнда слева, операция удаляет только правильный соответствующий вложенный список. Если удаление приводит к пустому списку, результатом будет null.

    Action a = () => Console.Write("a");
    Action b = () => Console.Write("b");
    
    var abbaab = a + b + b + a + a + b;
    abbaab();  // output: abbaab
    Console.WriteLine();
    
    var ab = a + b;
    var abba = abbaab - ab;
    abba();  // output: abba
    Console.WriteLine();
    
    var nihil = abbaab - abbaab;
    Console.WriteLine(nihil is null);  // output: True
    
  • Если список вызовов правого операнда не является непрерывным подсписком списка вызовов левого операнда, результатом операции является левый операнд. Например, удаление делегата, который не является частью делегата многоадресной рассылки, не приводит ни к каким изменениям и оставляет делегата многоадресной рассылки без изменений.

    Action a = () => Console.Write("a");
    Action b = () => Console.Write("b");
    
    var abbaab = a + b + b + a + a + b;
    var aba = a + b + a;
    
    var first = abbaab - aba;
    first();  // output: abbaab
    Console.WriteLine();
    Console.WriteLine(object.ReferenceEquals(abbaab, first));  // output: True
    
    Action a2 = () => Console.Write("a");
    var changed = aba - a;
    changed();  // output: ab
    Console.WriteLine();
    var unchanged = aba - a2;
    unchanged();  // output: aba
    Console.WriteLine();
    Console.WriteLine(object.ReferenceEquals(aba, unchanged));  // output: True
    

    В предыдущем примере также показано, что при удалении делегатов экземпляры делегатов сравниваются. Например, делегаты, созданные из оценки идентичных лямбда-выражений , не равны. Дополнительные сведения о равенстве делегатов см. в разделе операторов равенства делегатовспецификации языка C#.

  • Если левый операнд имеет nullзначение, результатом операции является null. Если правый операнд является null, результатом операции является левый операнд.

    Action a = () => Console.Write("a");
    
    var nothing = null - a;
    Console.WriteLine(nothing is null);  // output: True
    
    var first = a - null;
    a();  // output: a
    Console.WriteLine();
    Console.WriteLine(object.ReferenceEquals(first, a));  // output: True
    

Чтобы объединить делегаты, используйте + оператор.

Дополнительные сведения о типах делегатов см. в разделе Делегаты.

Оператор назначения вычитания -=

Выражение, использующее -= оператор, например

x -= y

Эквивалентен

x = x - y

За исключением того, что x оценивается только один раз.

В следующем примере показано, как использовать -= оператор:

int i = 5;
i -= 9;
Console.WriteLine(i);
// Output: -4

Action a = () => Console.Write("a");
Action b = () => Console.Write("b");
var printer = a + b + a;
printer();  // output: aba

Console.WriteLine();
printer -= a;
printer();  // output: ab

Оператор -= также используется для указания метода обработчика события, который нужно удалить при отмене подписки на событие. Дополнительные сведения см. в разделе Как подписаться и отменить подписку на события.

Перегрузка оператора

Определяемый пользователем тип может перегрузить оператор -. При перегрузке двоичного - оператора вы также неявно перегружаете -= оператор. Начиная с C# 14 определяемый пользователем тип может явно перегружать -= оператор, чтобы обеспечить более эффективную реализацию. Как правило, тип перегружает оператор -=, так как значение можно обновить на месте, а не выделить новый экземпляр для хранения результата вычитания. Если тип не предоставляет явной перегрузки, компилятор создает неявную перегрузку.

Спецификация языка C#

Дополнительные сведения см. в разделах «Унарный минус» и «Оператора вычитания»спецификации языка C#. Дополнительные сведения о перегрузке операторов составных назначений в C# 14 и более поздних версиях см. в спецификации определяемой пользователем функции составного назначения .

См. также