Following this very interesting issue which was originated from this question -
I want to take 1 steps back please (removed the dynamic environment) :
Looking at this code : ( a variant of this one)
void Main()
{
int a;
int b = 100;
Console.WriteLine(X.M(1, out a));
}
public class X
{
public int H=0;
public static X M(int x, out int y)
{
Console.WriteLine("x = "+x);
y = x;
return new X(x);
}
public X(){}
public X(int h)
{
H=h;
}
public static bool operator false(X x) {Console.WriteLine("in false operator for "+ x.H); return true; }
public static bool operator true(X x) {Console.WriteLine("in true operator for "+ x.H); return true; }
public static X operator &(X a, X b) {Console.WriteLine("in & operator for "+ a.H+","+b.H); return new X(); }
public static implicit operator bool (X x) {Console.WriteLine("in bool operator for "+ x.H);return true; }
}
The result is :
x = 1
in bool operator for 1
True
This is understood :
x = 1 is from the method itself ( using Console.Writeline) in bool operator for 1 is from the implicit operator from X to Bool
(so - Console.WriteLine treats the whole expression as Console.Writeline(bool))operator bool (X x)OK - So let's change
Console.WriteLine(X.M(1, out a));
to
Console.WriteLine(X.M(1, out a) && X.M(2, out b));
Now - the result is :
x = 1
in false operator for 1
in bool operator for 1
True
2 questions :
Why does this in false operator for 1 executes ? I don't see any reason for false to be present here.
I could understand why the right part in X.M(1, out a) && X.M(2, out b) won't executes ONLY if the left part is false - but again I don't see how the left part can be false. It does return true (according to my first code)
NB
I've read many times the answers from the post :
Jon said :
The second && is a normal && between two bool expressions - because Nop returns bool, and there's no &(X, bool) operator... but there is a conversion from X to bool.
So it's more like:
bool first = X.M(1, out a) && X.M(2, out b);
if (first && Nop(a, b))Now first is true even though only the first operand of && has been evaluated... so b really hasn't been assigned.
Still I don't understand : "first is true(????) even though only the first operand of && has been evaluated"

Firstly, don't forget that this is deliberately bizarre code, used to find a corner case. If you ever find a type that behaves like this in a genuine program, find the author and have a quiet word with them.
Still I don't understand : "first is true(????) even though only the first operand of && has been evaluated"
Yes, because of the way the && operand is handled in the case where the operands aren't bool. It's specified in section 7.12.2 of the C# spec:
The operation
x && yis evaluated asT.false(x) ? x : T.&(x, y)whereT.false(x)is an invocation of theoperator falsedeclared inT, andT.&(x, y)is an invocation of the selected operator in&. In other words,xis first evaluated andoperator falseis invoked on the result to determine ifxis definitely false. Then, ifxis definitely false, the result of the operation is the value previously computed forx. Otherwise,yis evaluated, and the selectedoperator &is invoked on the value previously computed forxand the value computed foryto produce the result of the operation.
So, in order:
X.M(1, out a) is invoked, to get a result - call it op1 for the momentX.false(op1) is invoked, and returns trueX.M(1, out a) && X.M(2, out b) is op1op1 to bool is invoked, and that returns true. This is due to overload resolution for Console.WriteLine.To answer your specific confusion:
but again I don't see how the left part can be false.It does return true (according to my first code)
It returns a value which is somewhat contradictory - it's false in that the false operator returns true, but it's true in that the conversion to bool returns true. Once you understand that it's the value returned by the false operator which determines whether or not to evaluate the second operand of &&, it should all be clear.
See more on this question at Stackoverflow