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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With