Skip to main content

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.

The inequality operator (!=) is a binary comparison operator that evaluates to true if its operands are not equal, and false otherwise. It functions as the strict logical negation of the equality operator (==).
bool result = operand1 != operand2;

Evaluation Mechanics by Type

The behavior of the != operator depends strictly on the type of the operands being evaluated:
  • Predefined Value Types (int, bool, double, etc.): Evaluates value inequality. It compares the underlying data of the operands.
  • User-Defined Value Types (struct): The != operator is not predefined for custom struct types. Attempting to use != on a standard custom struct without an explicit operator overload results in a compiler error (CS0019).
  • Nullable Value Types (Nullable<T>): Utilizes “lifted” operators. If both operands are null, != evaluates to false. If exactly one operand is null, it evaluates to true. If both operands possess values, the operator unwraps them and applies the underlying type’s != operator.
  • Reference Types (class, object): Evaluates reference inequality. It returns true if the operands point to different memory addresses on the heap, even if the data within those objects is identical.
  • Strings (string): Although string is a reference type, the != operator is overloaded to perform an ordinal, character-by-character value comparison rather than a reference comparison.
  • Tuples (ValueTuple): As of C# 7.3, tuples have compiler-synthesized support for the != operator. It evaluates to true if any corresponding elements in the tuples are not equal, performing a short-circuiting, element-wise comparison.
  • Delegates: Evaluates to true if the delegates have different target methods, different target object instances, or different invocation lists. Two delegates pointing to the exact same method but bound to different object instances are considered unequal.
  • Floating-Point Types (float, double): Follows IEEE 754 standards. Notably, NaN (Not a Number) is never equal to anything, including itself. Therefore, Double.NaN != Double.NaN evaluates to true.

Operator Overloading

User-defined types can overload the != operator to provide custom inequality logic (e.g., forcing a class to evaluate by value instead of reference, or enabling != for a struct). C# enforces a strict pairing constraint: if a type overloads !=, it must simultaneously overload ==. Furthermore, it is highly recommended to override Object.Equals() and Object.GetHashCode() to maintain consistent evaluation across the .NET framework and prevent compiler warnings (CS0660 and CS0661).
public readonly struct Point
{
    public int X { get; }
    public int Y { get; }

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

    // Overloading != requires overloading ==
    // This resolves CS0019 for this struct
    public static bool operator !=(Point left, Point right) => 
        left.X != right.X || left.Y != right.Y;

    public static bool operator ==(Point left, Point right) => 
        !(left != right);

    // Omitted for brevity: Overrides for Object.Equals() and Object.GetHashCode()
    // required to prevent CS0660 and CS0661 compiler warnings.
}

Compiler-Synthesized Inequality

For record types (both record class and record struct), the compiler automatically synthesizes the != operator. The synthesized operator performs a shallow member-wise inequality check of all properties and fields. It does not perform a recursive value-based check. If a record contains a standard reference type (such as an array or a List<T>), the synthesized operator will perform reference inequality on that specific member.

Boxing Constraints

When value types are boxed into object references, the != operator reverts to reference comparison. It evaluates the memory addresses of the boxed instances on the heap, not the unboxed values.
int val = 42;
object boxed1 = val;
object boxed2 = 42;

// Evaluates to true because boxed1 and boxed2 are distinct heap allocations
bool isNotEqual = boxed1 != boxed2; 
Master C# with Deep Grasping Methodology!Learn More