This is the story of a C# language specification change.
The specification changed because the 1.0 version of the C# spec disagreed with itself, and one of those locations was incorrect and broke a feature.
The change is in the section on “Conditional Logic Operators”. Version 1 of the spec states:
The later versions (starting with version 3) state:
Why the change?
Well, a couple sections later, the spec defines “User-Defined Conditional Logical Operators”. The C# Language does not allow you to create a user defined operator && or operator ||. Instead, you must define operator |, operator &, operator true and operator false. Here is the pertinent text:
The && and || operation is evaluated by combining the user-defined operator true or operator false with the selected user-defined operator:
The key points here are that for operator &&, x is checked to ensure that it is not false, and for operator ||, x is checked to ensure that it is not true.
The version 1.0 of the spec had serious limitations. User Defined Types that defined operator & or operator | would work with if and only if operator true and operator false were defined such that exactly one of them was true at all times.
Nothing in the language mandates that explicitly.
As a thought exercise, suppose you have a type that may be neither true nor false in some states. Maybe there are ranges of “true” and “false” and a range in between of “neither true nor false”.
If you want a concrete example, consider a type that has a single byte field. Its operator true returns true when all bits are 1. Its operator false returns true when all bits are 0. In all cases, to evaluate ‘x && y’, or ‘x || y’ requires both the left and right side of the operator. No short circuiting is possible.
That’s why the spec changed at version 3.
We felt the spec needed a little more explanation around this change. In ECMA version 5, we’re adding this note:
note: The reason that short circuiting uses the 'not true' and 'not false' conditions is to enable user defined conditional operators to define when short circuiting applies. User defined types could be in a state where
false. In those cases, neither && or || would short circuit.
The C# spec (thankfully) has relatively few locations where the spec disagrees with itself. But in a large document, it’s easy for them to creep in. Several people review and make corrections whenever we find them.
All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.