Nullable<T>: and overloaded operators, bool? & bool

c#, nullable

Solution

Operators on `Nullable<T>` are "lifted" operators. What this means is: if T has the operator, T? will have the "lifted" counterpart.

&& and || aren't really operators in the same sense as & and | - for example, they can't be overloaded - from the ECMA spec 14.2.2 Operator overloading:

The overloadable binary operators are: + - * / % & | ^ << >> == != > < >= <= Only the operators listed above can be overloaded. In particular, it is not possible to overload member access, method invocation, or the =, &&, ||, ??, ?:, checked, unchecked, new, typeof, as, and is operators.

Likewise, from the ECMA spec, 14.2.7 Lifted operators, the lifted operators are:

For the unary operators + ++ - -- ! ~

For the binary operators + - * / % & | ^ << >>

For the equality operators == !=

For the relational operators < > <= >=

So basically, the short-circuiting operators aren't defined as lifted operators.

[edit: added crib sheet]

Lifted operator: a compiler provided operator on `Nullable<T>`, based on the operators of T - for example: the `int` "+" operator gets "lifted" onto `int?`, defined as:

(int? x, int? y) => (x.HasValue && y.HasValue) ? (x.Value + y.Value) : (int?) null;

Operator overloading: the act of providing a custom operator implementation for a given type; for example `decimal` and `DateTime` provide various operator overloads

Short-circuiting: the normal behavior of `&&` and `||` (in many languages, including C++ and C#) - i.e. the second operand might not be evaluated - i.e.

(expression1, expression2) => expression1() ? expression2() : false;

Or perhaps a simpler example:

bool someFlag = Method1() && Method2();

if `Method1()` returns false, then `Method2()` isn't executed (since the compiler already knows that the overall answer is false). This is important if `Method2()` has side-effects, since as saving to the database...

Problem

- Why is operator '&' defined for bool?, and operator '&&' is not? - How exactly does this 1) bool? & bool? and 2) bool? and bool work? Any other "interesting" operator semantics on Nullable? Any overloaded operators for generic T?

Original source