Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Operator ?: with Nullable type Casting

Tags:

From the MSDN documentation, the following two snippets are equal:

bool value;
int x = (value) ? 0 : 1;

And

bool value;
int x;
if (value)
    x = 0;
else
    x = 1;

Great, wonderful. I use it all the time. Terse and effective.

If we try this with a nullable type, like so:

int? x = (value.HasValue) ? value.Value : null;

We get a compile-time error:

The type of conditional expression cannot be determined
because there is no implicit conversion between '{NullableType}' and null.

This compiles fine:

int? value;
int? x;

if (value.HasValue)
    x = value.Value;
else
    x = null;

So, I understand that the compiler requires an explicit cast in the way of (int?)null to compile the first statement. What I don't understand is why it is required in that statement, but not the If Else block.

like image 457
Michael Avatar asked Sep 12 '13 19:09

Michael


People also ask

How to use null conditional operator in c#?

A null-conditional operator applies a member access, ?. , or element access, ?[] , operation to its operand only if that operand evaluates to non-null; otherwise, it returns null . That is, If a evaluates to null , the result of a?. x or a?[x] is null .

Is null c# operator?

operator is known as Null-coalescing operator. It will return the value of its left-hand operand if it is not null. If it is null, then it will evaluate the right-hand operand and returns its result. Or if the left-hand operand evaluates to non-null, then it does not evaluate its right-hand operand.

What is conditional operator in C sharp?

A conditional operator in C#, is an operator that takes three operands (conditions to be checked), the value when the condition is true and value when the condition is false. A conditional operator is represented by the symbol '?:'.


1 Answers

null can represent any object-based datatype. You need to cast null as a datatype so it know what you are talking about.

int? x = (value.HasValue) ? value.Value : (int?)null;

I know, it sounds a bit strange.


To answer the questions in the comments:

Why is it not implicit though?
Yeah, I get that. But why do I not have to cast it in a If Else block?

Let's walk through the code.

Your else statement looks like this:

else x = null;

This means you are assigning the value of null to x. This is valid, because x is a int?, which takes nulls.

The difference comes when you have the ternary operator. It says: "assign the value of the operator into x". The question (and the reason for your error) is, what datatype is the result of the ternary operator?

From your code, you can't be sure, and the compiler throws its hands up.

int? x = (value.HasValue) ? value.Value : null;
// int?        bool             int        ??

What datatype is null? You are quick to say "well it's a int?, because the other side is a int and the result is a int?". The problem is, what about the following:

string a = null;
bool? b = null;
SqlConnectionStringBuilder s = null;

This is also valid, which means null can be used for any object-based datatype. This is why you have to explicitly cast null as the type you want to use, because it can be used for anything!


Another explanation (and possible more accurate):

You can't have an implicit cast between a nullable and a non-nullable value.

int is not-nullable (it's a structure), where null is. This is why in Habib's answer you can put the cast on either the left or right side.

like image 63
gunr2171 Avatar answered Sep 22 '22 09:09

gunr2171