Why doesn't bool?
support lifted &&
and ||
? They could have lifted the true
and false
operators which would have indirectly added lifted &&
and ||
.
The operators |
and &
are already lifted and implement the correct Three-valued logic. But of course they are not short circuiting like ||
and &&
.
The question is why they decided not to lift those operators when creating the specification. So "It's like this because the spec says so" is no answer to the "why?".
When lifting true
and false
so that null
is neither true
nor false
:
public static bool operator true(bool? x)
{
return x.HasValue && x.Value
}
public static bool operator false(bool? x)
{
return x.HasValue && !x.Value
}
This would have resulted in &&
and ||
behaving just like their non short-circuiting counterparts. Except that false && anything
and true || anything
would short circuit (false
and true
are no compile time constants in these two examples).
This would work very similar to the DBBool example on MSDN.
I see no surprising or dangerous behavior introduced by lifting these operators. Did I miss something?
I have read another SO question on this, but found none of the answers satisfying.
Jeff Yates's answer shows a nice reason for why lifting the true
/false
operators isn't optimal, it doesn't explain why lifting &&
and ||
directly is bad. Since operator lifting is compiler magic that special cases Nullable<T>
it doesn't need to follow the overloading rules for normal types and thus would be able to offer &&
/||
without lifting true
.
NULL AND true , NULL and NULL, FALSE OR NULL
is .. NULL, which is neither true nor false – Vespertinefalse
applied tonull
returns false. This leads to&&
not short circuiting and returningnull&anything
instead. – Yandtrue(x) == false(x);
. That would hardly seem to make any sense. – NeronWHERE
clause in SQL treatsNULL
as result of conditional expression asfalse
, exampleWHERE X = NULL
return empty set, because it is always false, even for NULL. so this is just a projection of three-state logic to two-state logic. – Superegotrue(x) == false(x)
– Superegotrue
norfalse
? it will returnfalse
for both. – Superegov = null | true;
and it will compile. Its returns true, howeverv = null | false
is null instead of false because you cant say it is false since null is not false. An easy way to thin of it is what CodeInChaos said to me, pretend null is (false&&true) and do the operations ;). I believe the question is, if null & boolval is legal why does null && boolval not compile. He doesnt see any harmful effects – Acyclicfalse&&true
but that it can assume both values. Probably just a misleading formulation on your part. – Yand&
and|
but not&&
and||
. – Yand&&
and||
) can't be overloaded, and this rule was there before nullables. They decided to play their own rules :) – Superego&&
and||
on your own types by overloadingtrue
andfalse
. TheDBBool
type in the example I posted does exactly that. And of course all lifted operators are compiler magic and not possible by simply adding operators toNullable<T>
. In particular they are only available if the underlying type has them, and they mimic the types the corresponding operators on the underlying type use(made nullable of course). – Yand