Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How null-coalsescing operator works

I got three classes (classA, classB and classC) that inherit from an interface 'IFoo'; if use this

var fooItem = (request.classAitem ?? (request.classBitem  as IFoo ?? request.classCitem)) 

or

var fooItem = (request.classAitem ?? request.classBitem ?? request.classCitem as IFoo)

it works just fine but other combinations won't even compile:

var fooItem = (request.classAitem as IFoo ?? request.classBitem ?? request.classCitem)

or

var fooItem = (request.classAitem ?? request.classBitem ?? request.classCitem) as IFoo

It seems to me that in some cases the compiler implicitly unboxes the child classes to their IFoo interface but in some other cases don't. What do you guys think?

like image 564
Zalomon Avatar asked Aug 08 '16 08:08

Zalomon


People also ask

What is a null-coalescing operator used for?

A null-coalescing operator is used to check such a variable (of nullable type) for null. If the variable is null, the null-coalescing operator is used to supply the default value while assigning to a variable of non-nullable type.

Which of the following is null-coalescing operator?

Introduction. The ?? operator is also known as the null-coalescing operator. It returns the left side operand if the operand is not null else it returns the right side operand.

What is the benefit of coalescing?

The coalesce function searches through all of the parameters, left to right, and returns the first one that is not NULL. So in this example, it will return the value of A, unless A is Null, in which case it will return the value of B, unless B is also Null, in which case it will return the value of C ... etc., etc.

What is null conditional and null coalescing in C#?

it is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise, it returns the right operand. In cases where a statement could return null, the null-coalescing operator can be used to ensure a reasonable value gets returned.


1 Answers

In both of your examples that don't work, because ?? is right-associative, we're first trying to determine the data type of this expression:

request.classBitem ?? request.classCitem

The data type can only be the data type of one of its inputs, if the data types are different. There's obviously no conversions available in either direction here and so you get a compiler error. Note that the compiler will not decide that the data type here is IFoo just because both classes happen to implement it (and if it did, what would happen if they both implemented multiple common interfaces?)

Compare this to your first two examples. In the first, we first consider this expression:

request.classBitem  as IFoo ?? request.classCitem

The type of this expression is either IFoo or whatever the data type of request.classCitem is. There's a conversion from the type of request.classCitem to IFoo and so that's obviously selected and so the entire expression's data type is IFoo. That is then used to determine the type of the overall expression (again, IFoo).

The second case is very similar, since ?? is right associative1, we first have to determine the type of:

request.classBitem ?? request.classCitem as IFoo

And again, we have a choice between IFoo and whatever the data type of request.classBitem is. There's a conversion to IFoo and so that is chosen.

1And note, also, that it means the parentheses in the first example are superfluous.

like image 153
Damien_The_Unbeliever Avatar answered Sep 28 '22 15:09

Damien_The_Unbeliever