> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C# Subtraction

The `-` operator in C# functions as both a unary operator for numeric negation and a binary operator for arithmetic subtraction, enumeration subtraction, delegate removal, and pointer arithmetic. Its behavior, return type, and overflow mechanics are resolved at compile-time based on the arity of the operation, the static types of its operands, and the evaluation context.

## Unary Negation

When applied to a single operand, the `-` operator computes the numeric negation of that operand, effectively subtracting the operand from zero.

* **Supported Types:** Predefined for `int`, `long`, `float`, `double`, and `decimal`.
* **Type Mechanics:** When the unary `-` operator is applied to a `uint`, the operand is implicitly promoted to a `long`, and the operation returns a `long`. The operator is not defined for `ulong`; attempting to apply it to a `ulong` results in a compile-time error (CS0023).
* **Overflow Mechanics:** The two's complement representation of integers means the absolute value of `int.MinValue` and `long.MinValue` exceeds the maximum positive value of their respective types. Applying the unary `-` to these minimum values in an `unchecked` context results in a wrap-around, returning the minimum value itself. In a `checked` context, this operation throws a `System.OverflowException`.

```csharp theme={"dark"}
int positiveInt = 5;
int negativeInt = -positiveInt;

uint unsignedInt = 10U;
long negatedUnsigned = -unsignedInt; // Implicitly promoted to long

int min = int.MinValue;
int uncheckedNegation = unchecked(-min); // Evaluates to int.MinValue
int checkedNegation = checked(-min);     // Throws System.OverflowException
```

## Binary Subtraction

When applied to two operands, the `-` operator computes the arithmetic difference between the left operand (minuend) and the right operand (subtrahend).

* **Supported Types:** Predefined for all standard numeric types (`int`, `uint`, `long`, `ulong`, `float`, `double`, `decimal`).
* **Type Mechanics:** If the operands are of different types, C# applies implicit numeric promotions to convert them to a common type before performing the subtraction. The return type matches this promoted type.
* **Overflow Mechanics:** For integral types, if the mathematical difference cannot be represented within the bounds of the return type, an arithmetic overflow occurs. In an `unchecked` context, the high-order bits are discarded, resulting in a wrap-around. In a `checked` context, the operation throws a `System.OverflowException`. Floating-point subtraction (`float`, `double`) never throws an overflow exception; instead, it yields positive or negative infinity.

```csharp theme={"dark"}
int a = 10;
int b = 3;
int difference = a - b;

float c = 5.5f;
double d = 2.2;
double floatDoubleDifference = c - d; // float is promoted to double

int max = int.MaxValue;
int overflowUnchecked = unchecked(max - (-1)); // Evaluates to int.MinValue
int overflowChecked = checked(max - (-1));     // Throws System.OverflowException
```

## Lifted Operators for Nullable Types

For nullable value types (`T?`), C# automatically provides lifted versions of the predefined unary and binary `-` operators. The lifted operator evaluates the `HasValue` property of its operands. If either or both operands evaluate to `null`, the result of the operation is `null`. Otherwise, the operator unwraps the underlying values, applies the standard `-` operator, and wraps the result back into a nullable type.

```csharp theme={"dark"}
int? val1 = 10;
int? val2 = null;

int? binaryResult = val1 - val2; // Evaluates to null
int? unaryResult = -val2;        // Evaluates to null
```

## DateTime and TimeSpan Subtraction

C# provides predefined binary `-` operators for the `System.DateTime`, `System.DateTimeOffset`, and `System.TimeSpan` structs to handle chronological arithmetic:

1. **DateTime and DateTime:** Subtracting a `DateTime` from another `DateTime` yields a `System.TimeSpan` representing the duration between the two points in time.
2. **DateTime and TimeSpan:** Subtracting a `TimeSpan` from a `DateTime` yields a new `DateTime` decremented by the specified duration.
3. **TimeSpan and TimeSpan:** Subtracting a `TimeSpan` from another `TimeSpan` yields a new `TimeSpan` representing the difference between the two durations.

```csharp theme={"dark"}
System.DateTime d1 = new System.DateTime(2023, 1, 10);
System.DateTime d2 = new System.DateTime(2023, 1, 5);
System.TimeSpan duration = d1 - d2; // Yields TimeSpan representing 5 days

System.DateTime decremented = d1 - duration; // Yields DateTime(2023, 1, 5)
```

## Enumeration Subtraction

C# provides predefined binary `-` operators for all `enum` types, supporting two distinct operations:

1. **Enum and Enum:** Subtracting two enum values of the same type yields the difference between their underlying numeric values. The return type is the underlying integral type of the enumeration.
2. **Enum and Integer:** Subtracting an integer from an enum value yields a new enum value decremented by the integer amount. The return type is the enumeration type itself.

```csharp theme={"dark"}
System.DayOfWeek currentDay = System.DayOfWeek.Wednesday;
System.DayOfWeek previousDay = currentDay - 2; // Enum and Integer yields Enum (Monday)

int daysBetween = System.DayOfWeek.Friday - System.DayOfWeek.Monday; // Enum and Enum yields Int32 (4)
```

## Delegate Removal

For operands of concrete delegate types (such as `System.Action`, `System.Func<T>`, or custom delegate signatures), the binary `-` operator performs delegate removal. It evaluates the invocation lists of both operands. The operator is not defined on the `System.Delegate` base class itself; attempting to use it on variables typed strictly as `System.Delegate` results in a compile-time error (CS0019).

* **Mechanics:** If the right operand's invocation list is a contiguous sublist of the left operand's invocation list, the operator returns a new delegate with that sublist removed. If the right operand's invocation list matches multiple sublists within the left operand's invocation list, the `-` operator removes only the *last* matching contiguous sublist. If the right operand is not found, or if the right operand is `null`, it returns the left operand unchanged. If the removal results in an empty invocation list, the operator returns `null`.

```csharp theme={"dark"}
System.Action action1 = () => System.Console.Write("A");
System.Action action2 = () => System.Console.Write("B");

System.Action combined = action1 + action2;
System.Action removed = combined - action2; // Returns a delegate equivalent to action1
```

## Pointer Arithmetic

In an `unsafe` context, the binary `-` operator supports pointer arithmetic with two distinct signatures:

1. **Pointer and Integer:** Subtracting an integer offset from a pointer returns a new pointer of the same type, decremented by the offset multiplied by the size of the pointer's underlying type.
2. **Pointer and Pointer:** Subtracting a pointer from another pointer of the same type returns a `long` representing the distance (in elements, not bytes) between the two memory addresses.

```csharp theme={"dark"}
unsafe
{
    int[] numbers = new int[5];
    fixed (int* ptr1 = &numbers[0])
    fixed (int* ptr2 = &numbers[3])
    {
        int* decrementedPtr = ptr2 - 1; // Pointer and Integer
        long elementDistance = ptr2 - ptr1; // Pointer and Pointer yields 3L
    }
}
```

## Operator Overloading

User-defined types (`struct` or `class`) can overload the `-` operator to define custom negation or subtraction logic. Overloads must be declared as `public static`. If a type overloads the binary `-` operator, it does not automatically overload the `-=` compound assignment operator; however, C# automatically evaluates `x -= y` as `x = x - y` using the overloaded binary operator.

```csharp theme={"dark"}
public readonly struct Point
{
    public readonly int X;
    public readonly int Y;

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    // Unary overload signature
    public static Point operator -(Point p)
    {
        return new Point(-p.X, -p.Y);
    }

    // Binary overload signature
    public static Point operator -(Point left, Point right)
    {
        return new Point(left.X - right.X, left.Y - right.Y);
    }
}
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
