Reputation: 1386
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
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
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
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