How Did I Miss This?

Published 24 August 07 12:13 AM

I consider myself relatively savvy in the ways of C#.  However, I apparently missed a pretty cool 2.0 operator back in the day and just stumbled over it tonight (by way of researching it after being absolutely sure that the code I was looking at was wrong).  At any rate, I'm talking about the null coalescing operator ("??").  Rather than spend more time duplicating what has already been said about it, I'll just point you to R. Aaron Zupancic's post on the topic.

One thing that I do want to point about this technique is that it is a bit more (slightly) than syntactic sugar - as it actually generates different IL than the same task implemented with the ternary operator.  For example, here is some typical ternary-based code.

   1: private static void SayHello2(string name) {
   2:     Console.WriteLine(name != null ? name : "Nobody to greet");
   3: }

And here is the IL that the compiler produces.

   1: .method private hidebysig static void  SayHello2(string name) cil managed
   2: {
   3:   // Code size       19 (0x13)
   4:   .maxstack  8
   5:   IL_0000:  nop
   6:   IL_0001:  ldarg.0
   7:   IL_0002:  brtrue.s   IL_000b
   8:   IL_0004:  ldstr      "Nobody to greet"
   9:   IL_0009:  br.s       IL_000c
  10:   IL_000b:  ldarg.0
  11:   IL_000c:  call       void [mscorlib]System.Console::WriteLine(string)
  12:   IL_0011:  nop
  13:   IL_0012:  ret
  14: } // end of method Program::SayHello2

Now - consider the same method using the null coalescing operator. 

   1: private static void SayHello1(string name) {
   2:     Console.WriteLine(name ?? "Nobody to greet");
   3: }

The corresponding IL is as follows.

   1: .method private hidebysig static void  SayHello1(string name) cil managed
   2: {
   3:   // Code size       18 (0x12)
   4:   .maxstack  8
   5:   IL_0000:  nop
   6:   IL_0001:  ldarg.0
   7:   IL_0002:  dup
   8:   IL_0003:  brtrue.s   IL_000b
   9:   IL_0005:  pop
  10:   IL_0006:  ldstr      "Nobody to greet"
  11:   IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)
  12:   IL_0010:  nop
  13:   IL_0011:  ret
  14: } // end of method Program::SayHello1

So what's the difference here?  Practically speaking, the difference between the 2 is that the null coalescing operator results in IL code that duplicates the method argument after it's been loaded onto the stack, and pops it off the stack if the conditional test returns false.  In contrast, the ternary operator, rather than duplicating the method argument on the stack, performs an additional load operation to add the duplicate value onto the stack.

Now, does this mean that if you rewrite all your code, replacing ternary null comparisons with the coalescing operator, your code will perform orders of magnitude better??  Not even close.  However, I find it interesting that the 2 methods are actually different at the IL level - and if you've read this far, you find it interesting enough!

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# leppie said on August 24, 2007 5:16 AM:

Look here for some wacky usage :)

http://xacc.wordpress.com/2007/08/23/interesting-c-construct/

# skware said on August 24, 2007 8:10 AM:

The reason the IL is different:

Console.WriteLine(SomeMethodWithSideEffects() != null ? SomeMethodWithSideEffects() : someValue);

# hdierking said on August 24, 2007 10:29 AM:

skware - doh!  Yup - makes total sense.  Amazing what a little sleep can do!

# BenScheirman said on August 24, 2007 3:39 PM:

Yeah I really love that operator.  I stumbled on it about 6 months ago... strange how it's not in more examples/material on the net.

Leave a Comment

(required) 
(optional)
(required) 

About hdierking

I am currently the Editor-in-Chief for MSDN Magazine. I joined Microsoft in 2006 as a product planner with the certification team at Microsoft Learning. Prior to that, I spent my career as a developer and later as an architect. My main technology passions include pretty much anything on language theory, agile development, and service-oriented architecture.
Page view tracker