Recently i find out, that the following code compiles and works as expected in VS2017. But i can't find any topic/documentation on this. So i'm curious is it legit to use this syntax:
class Program
{
static void Main(string[] args)
{
var o = new object();
Console.WriteLine(o is null);
o = null;
Console.WriteLine(o is null);
Console.ReadLine();
}
}
BTW this is not working in VS2015
Yes, it is valid to write o is null, but this is not equivalent to o == null. The code
static bool TestEquality(object value) => value == null;
compiles into following IL instructions.
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: ceq
IL_0004: ret
The pattern matching case compiled in following manner:
static bool TestPatternMatching(object value) => value is null;
IL_0000: ldnull
IL_0001: ldarg.0
IL_0002: call bool [System.Runtime]System.Object::Equals(object, object)
IL_0007: ret
So, pattern matching o is null is equivalent to
Object.Equals(value, null);
So, in most cases o is null and o == null will behave in same way. Except equality variant is a bit faster. BUT! Things will change dramatically, if we replace object with following class.
class TestObject
{
public static bool operator ==(TestObject lhs, TestObject rhs) => false;
public static bool operator !=(TestObject lhs, TestObject rhs) => false;
}
and methods with
static bool TestEquality(TestObject value) => value == null;
static bool TestPatternMatching(TestObject value) => value is null;
The pattern matching will stay same, but the equality variant will use following IL
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: call bool PatternMatchingTest.TestObject::op_Equality(class PatternMatchingTest.TestObject, class PatternMatchingTest.TestObject)
IL_0007: ret
Here we can see, that == operator is using TestObject's overload as expected. But o is null and o==null will give different results. So be careful using pattern matching is operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With