1

I have a condition

if (driver?.VistrackId == 555)

it equivalent (in IL code, not C# code):

if (driver != null && driver.VistrackId == 555)

right?

4
  • if (driver?.VistrackId == 555) is this compiling ? Commented Mar 10, 2018 at 13:16
  • you can compare the IL in LINQPad Commented Mar 10, 2018 at 13:18
  • 1
    if((driver == null ? null : driver.VistrackId) == 555) Commented Mar 10, 2018 at 13:22
  • 1
    This is not IL, this is still C#, but without syntactic sugar. Commented Mar 10, 2018 at 13:24

3 Answers 3

4

Not exactly

It's better Since this notation is thread safe

See Null-conditional Operators on MSDN.

Sign up to request clarification or add additional context in comments.

3 Comments

I think the thread-safety in the article is directed towards handling delegates, not necessarily towards handling variables. It depends on the situation if it is actually thread-safe. See this answer for a discussion on the thread-safety of the operator.
@RMH but as I understand this operation is kind of atomic, and you can't set null your variable during null propagation is processed, even you set object to null you still be referencing initial object
my apologies, I misinterpreted your meaning (and the doc's) of 'thread safe' here. I agree that the variable cannot become null during its null-check exactly as you stated. In that sense it is a 'thread-safe null-check'. However, this does not hold for the called property / method (VistrackId in the post's case).
2

That's correct. The "?" checks for null, and if it's not null, the "." continues the interrogation of the object

Comments

1

This code generates the following IL

var driver = new {VistrackId = 1};

if (driver?.VistrackId == 555)
{
    Console.WriteLine("?. operator");
}

IL:

IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  newobj      <>f__AnonymousType0<System.Int32>..ctor
IL_0007:  stloc.0     // driver
IL_0008:  ldloc.0     // driver
IL_0009:  brtrue.s    IL_000E
IL_000B:  ldc.i4.0    
IL_000C:  br.s        IL_001B
IL_000E:  ldloc.0     // driver
IL_000F:  call        <>f__AnonymousType0<System.Int32>.get_VistrackId
IL_0014:  ldc.i4      2B 02 00 00 
IL_0019:  ceq         
IL_001B:  stloc.1     
IL_001C:  ldloc.1     
IL_001D:  brfalse.s   IL_002C
IL_001F:  nop         
IL_0020:  ldstr       "?. operator"
IL_0025:  call        System.Console.WriteLine
IL_002A:  nop         
IL_002B:  nop         
IL_002C:  ret    

Code with == null

var driver = new {VistrackId = 1};


if (driver != null && driver.VistrackId == 555)
{
    Console.WriteLine("== null");
}

IL

IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  newobj      <>f__AnonymousType0<System.Int32>..ctor
IL_0007:  stloc.0     // driver
IL_0008:  ldloc.0     // driver
IL_0009:  brfalse.s   IL_001A
IL_000B:  ldloc.0     // driver
IL_000C:  callvirt    <>f__AnonymousType0<System.Int32>.get_VistrackId
IL_0011:  ldc.i4      2B 02 00 00 
IL_0016:  ceq         
IL_0018:  br.s        IL_001B
IL_001A:  ldc.i4.0    
IL_001B:  stloc.1     
IL_001C:  ldloc.1     
IL_001D:  brfalse.s   IL_002C
IL_001F:  nop         
IL_0020:  ldstr       "== null"
IL_0025:  call        System.Console.WriteLine
IL_002A:  nop         
IL_002B:  nop         
IL_002C:  ret         

They are slightly different

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.