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’.
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.
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!
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”);
Thanks a lot for this little article :)
I can understand better the code I’m reading now