C# and question marks

One cool operators that C# offers us is ?? But before ?? we should know what does ? after variable type name. So, let’s take both of these question marks and let’s see what they are. Also let’s jump for a while behind compilator to see IL code that compiler produces.

Let’s start with single question mark. Single quetsion mark after variable type tells to compilator that this variable is Nullable<T>. To see if my statement holds true let’s look at the following code.

class Program
{
   
static void Main(string[] args)
    {
        Int32? x;
        Nullable<Int32> y;
    }
}

There are two lines of code in method Main(). First of them declares Int32 type variable using question mark. Second line declares Nullable<Int32>. Let’s see how these lines look like after compiling the code.

method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
 
// Code size       2 (0x2)
  .maxstack  0
  .locals init ([0] valuetype [mscorlib]System.Nullable`1<Int32> x,
           [1] valuetype [mscorlib]System.Nullable`1<Int32> y)
  IL_0000:  nop
  IL_0001:  ret
}
// end of method Program::Main

As we can see, both of them will be Nullable<Int32> after compiling.

Now let’s deal with double question mark that is operator. We will use code given in previous example and we will extend it so variable x is null and variable y has value 15. This time we need also some output, so I added two lines to deal with console. The code is here.

class Program
{
   
static void Main(string
[] args)
    {
        Int32? x =
null
;
        Nullable<Int32> y = 15;
       
Console
.WriteLine(x ?? y);
       
Console.ReadLine();
    }
}

When we run this code we will get 15 as output on console window. Therefore we can say that operator ?? works as COALESCE function in SQL Server. COALESCE returns first non-null value from it’s argument list. Let’s look at the following SQL statement.

SELECT COALESCE(null, notes, description) FROM contacts WHERE contact_id=10

It returns value of field notes if notes is not null and value of description otherwise. It returns null only if description and notes are both nulls. Can we use something like this also using ?? operator? Of course, no problem. Run the following code.

class Program
{
   
static void Main(string
[] args)
    {
        Int32? x =
null
;
        Nullable<Int32> y =
null
;
       
Console
.WriteLine(x ?? y ?? 10);
       
Console.ReadLine();
    }
}

After running the code we will see value 10 written on console window.

One thing we can’t do is using different types around ?? operator. By example, the following code

class Program
{
   
static void Main(string
[] args)
    {
        Int32? x =
null
;
       
string y = "test"
;
       
Console
.WriteLine(x ?? y);
       
Console.ReadLine();
    }
}

produces the following error: Operator ‘??’ cannot be applied to operands of type ‘int?’ and ‘string’.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    4 thoughts on “C# and question marks

    • January 7, 2008 at 2:38 am
      Permalink

      While ur at it I would have added the ternary operator:

      bool isOdd = (1 == i % 2) ? true : false;

      nullable types, null coalescing are more related, but the article title is “… question marks”. Ternary opertator is overlooked a lot and it can be “nested” to do more complex operations.

    • January 7, 2008 at 3:55 pm
      Permalink

      Bart – except in your example you don’t need the ternary operator.

      bool isOdd = (1 == i%2);

      That obviously suffices.

      Agreed though, that it is overlooked a lot, and it’s a pain in the eye (use 3-letter word of your choosing) to see code like:

      if (something.Valid())

      return true;

      else

      return false;

      Yuck!

    • January 8, 2008 at 4:46 pm
      Permalink

      Actually, the best place for a ternary is where an if() would be completely wrong:

      Console.WriteLine(“Your answer was {0}. This {1} correct”, myAnswer, isCorrect(myAnswer) ? “IS” : “is NOT”);

    • February 17, 2012 at 10:07 am
      Permalink

      Thanks a lot for this little article :)

      I can understand better the code I’m reading now

    Leave a Reply

    Your email address will not be published. Required fields are marked *