The "is" type pattern expression for null check
Obviously the 2 implementations are very similar, the difference would be negligible in memory, allocations, and cycles.
The compiler basically treats them as follows (for reference types)
First
MyType myType = SomeMethod();
if (myType != null)
{
Console.WriteLine(myType.ToString());
}
Second
MyType myType2;
if ((object)(myType2 = SomeMethod()) != null)
{
Console.WriteLine(myType2.ToString());
}
Probably better seen with the IL
First
IL_0000: ldarg.0
IL_0001: call instance class C/MyType C::SomeMethod()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0015
IL_000a: ldloc.0
IL_000b: callvirt instance string[mscorlib] System.Object::ToString()
IL_0010: call void[mscorlib] System.Console::WriteLine(string)
Second
IL_0015: ldarg.0
IL_0016: call instance class C/MyType C::SomeMethod()
IL_001b: dup
IL_001c: stloc.1
IL_001d: brfalse.s IL_002a
IL_001f: ldloc.1
IL_0020: callvirt instance string[mscorlib] System.Object::ToString()
IL_0025: call void[mscorlib] System.Console::WriteLine(string)
Note : You can check out the disassembly, IL and jit-asm here
The IL difference is basically 2 opcodes:
dup
: Copies the current topmost value on the evaluation stack, and then pushes the copy onto the evaluation stack.Ldloc
: Loads the local variable at a specific index onto the evaluation stack.
When Jitted, it would most likely optimize into the same instructions anyway
Summary
- There is no appreciable technical difference.
- Yeah the
is
version is a bit neater and a little more succinct I guess. - It's probably more printable characters, so if you have printable character OCD or suffer brutal code reviews, it might not be a good thing
- If you like it and your team likes it, go with it.
- It's not really my cup of tea