My IDE (Rider) keeps suggesting I use
if(s is { })
For null checks, in place of
if(s == null)
After some reaserch it seems like this is becoming the canonical way to do null checks in c#, and it clearly does have some benifits.
However in unity, there are really good reasons why you generally don't want to bypass the overriden equality operator. In other instances where this would happen, like the various null coalescing operators, I get very nice warnings about them not being safe with monobehaviour objects.
The above code generates no such warnings.
My question is, is this actually a safe way to do a null check on monobehaviours or should we still prefer explicit use of ==
?
After reading up on @Oliver's comment, and playing around with it on sharplab, I now have a better understanding on why this is safe.
All of the following
var s = new P();
if(s is {})
{
Foo();
}
if(s is object)
{
Foo();
}
if(s is not null)
{
Foo();
}
if(!(s == null))
{
Foo();
}
Produces the exact same
if (p != null)
{
Foo();
}
When lowered.
Even more complicated patterns such as
var nameToMatch = Name.James;
return s switch
{
{ firstName: Name.None } => throw new Exception("Person has no name"),
{ } when s.firstName == nameToMatch => true,
{ } when s.firstName != nameToMatch => false,
null => throw new Exception("Person was null!"),
_ => throw new ArgumentOutOfRangeException()
};
Is simply lowered to
Name name2 = Name.James;
P p2 = p;
if (p2 != null)
{
if (p2.firstName == Name.None)
{
throw new Exception("Person has no name");
}
if (p.firstName == name2)
{
return true;
}
if (p.firstName != name2)
{
return false;
}
throw new ArgumentOutOfRangeException();
}
throw new Exception("Person was null!");
All of which use the safe-for-unity == null checks