# - 和 -= 运算符（C# 参考）- and -= operators (C# reference)

- 运算符受内置数字类型和委托类型的支持。The - operator is supported by the built-in numeric types and delegate types.

## 委托删除Delegate removal

• 如果两个操作数都为非空，并且右侧操作数的调用列表是左侧操作数调用列表的正确连续子列表，则该操作的结果是通过从左侧操作数的调用列表中删除右侧操作数的条目而获得的新调用列表。If both operands are non-null and the invocation list of the right-hand operand is a proper contiguous sublist of the invocation list of the left-hand operand, the result of the operation is a new invocation list that is obtained by removing the right-hand operand's entries from the invocation list of the left-hand operand. 如果右侧操作数的列表与左侧操作数列表中的多个连续子列表匹配，则仅删除最右侧的匹配子列表。If the right-hand operand's list matches multiple contiguous sublists in the left-hand operand's list, only the right-most matching sublist is removed. 如果删除行为导致出现空列表，则结果为 nullIf removal results in an empty list, the result is 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

• 如果右侧操作数的调用列表不是左侧操作数调用列表的正确连续子列表，则该操作的结果是左侧操作数。If the invocation list of the right-hand operand is not a proper contiguous sublist of the invocation list of the left-hand operand, the result of the operation is the left-hand operand. 例如，删除不属于多播委托的委托不会执行任何操作，从而导致不变的多播委托。For example, removing a delegate that is not part of the multicast delegate does nothing and results in the unchanged multicast delegate.

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


前面的示例还演示了在删除委托期间对委托实例进行比较。The preceding example also demonstrates that during delegate removal delegate instances are compared. 例如，通过计算相同的 Lambda 表达式生成的委托不相等。For example, delegates that are produced from evaluation of identical lambda expressions are not equal. 有关委托相等性的详细信息，请参阅 C# 语言规范委托相等运算符部分。For more information about delegate equality, see the Delegate equality operators section of the C# language specification.

• 如果左侧操作数为 null，则操作结果为 nullIf the left-hand operand is null, the result of the operation is null. 如果右侧操作数为 null，则操作的结果是左侧操作数。If the right-hand operand is null, the result of the operation is the left-hand operand.

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


## 减法赋值运算符 -=Subtraction assignment operator -=

x -= y


x = x - y


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