The precedence of the operators in question seems to be copied directly from the precedence in the C (and C++) programming language.
Now in C, they don't use distinct types for integers and booleans. For example they could write:
if (i | j && x > 0) // cf. the result2 of your question
and this should mean "the integers i
and j
bitwise or'ed gives something nonzero AND the number x
is positive". So |
and &
are supposed to be mostly used when the operands are thought of as integers (many-bit numbers), and ||
and &&
are supposed to be mostly used when the operands are thought of as booleans.
So it might seem natural in C that |
binds more strictly than &&
.
In C# we have a higher degree of type safety, and there are no conversions from Int32
to Boolean
or from Boolean
to Int32
. Therefore it is no longer possible to "mix" things, and the precedence no longer feels natural.
I guess in theory in C#, one could make the operator
public static bool operator |(bool b, bool c)
have a different precedence than the operator
public static int operator |(int i, int j)
but it wouldn't really make things better?
I think it's very rare that people use boolean non-short-circuit operators like |
and short-circuit operators like &&
in the same expression, but when they do, they should either be very careful about precedence, or just put the parenthesis ()
there (it will also make the intention more clear).