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


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

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

Сведения об арифметическом операторе - см. в разделе Операторы унарного плюса и минуса и Оператор вычитания - в статье Арифметические операторы.

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

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

  • Если оба операнда не равны 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#

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

См. также