Pawel
Pawel

Reputation: 1386

What is the difference between "is not null" and "!= null"?

With the release of C# 9.0, the negated null constant pattern was introduced.

The documentation for pattern matching states:

Beginning with C# 9.0, you can use a negated null constant pattern to check for non-null, as the following example shows:

if (e is not null)
{
    // ...
}

Is there any difference between e is not null and e != null, besides the syntax?

Upvotes: 77

Views: 34887

Answers (3)

Brian Phiri
Brian Phiri

Reputation: 11

is not null helps the null state analyzer track nullability, != null only checks at runtime. Therefore, pattern matching can prevent null reference exceptions, particularly in LINQ chains where null state tracking is important. Pattern matching verifies null safety throughout the entire chain.

Upvotes: 1

mamen
mamen

Reputation: 1703

The only difference (besides the syntax) is, that the compiler guarantees that no user-overloaded operator is called when using is not null instead of != null (or is null instead of == null).

From operator overloading:

A user-defined type can overload a predefined C# operator. That is, a type can provide the custom implementation of an operation in case one or both of the operands are of that type. The Overloadable operators section shows which C# operators can be overloaded.

Upvotes: 24

Kyle B
Kyle B

Reputation: 2909

The main difference between e != null and e is not null is the way the the compiler executes the comparison.

Microsoft: "The compiler guarantees that no user-overloaded equality operator == is invoked when expression x is null is evaluated."

Bottom Line: If you are writing code that you don't want to depend on someone's implementation of the != and == operators, use is null and is not null because it is safer.

See the following example:

public class TestObject
{
  public string Test { get; set; }

  // attempt to allow TestObject to be testable against a string
  public static bool operator ==(TestObject a, object b)
  {
    if(b == null)
      return false;
    
    if(b is string)
      return a.Test == (string)b;

    if(b is TestObject)
      return a.Test == ((TestObject)b).Test;

    return false;
  }

  public static bool operator !=(TestObject a, object b)
  {
    if(b == null)
      return false;
    
    if(b is string)
      return a.Test != (string)b;

    if(b is TestObject)
      return a.Test != ((TestObject)b).Test;

    return false;
  }
}

If you have code that needs to ensure that an object isn't null, using is not null will give you better results with TestObject than using != null because the overload of the ==/!= operators is a little odd.

Console example 1:

TestObject e = null;

if(e == null)
  Console.WriteLine("e == null");

if(e is null)
  Console.WriteLine("e is null");

Output: e is null

Console example 2:

TestObject e = new TestObject();

if(e != null)
  Console.WriteLine("e != null");

if(e is not null)
  Console.WriteLine("e is not null");

Output: e is not null

Neither overloaded operator is implemented "correctly" so the Console never outputs e == null or e != null.

Upvotes: 83

Related Questions