关注来自this very interesting issue问题的this -
我想退步1步(删除动态环境):
查看此代码:( 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; }
}
结果是:
x = 1
in bool operator for 1
True
这是理解的:
x = 1
来自方法本身(使用Console.Writeline
)in bool operator for 1
来自X
到Bool
的隐式运算符
(所以 - Console.WriteLine
将整个表达视为Console.Writeline(bool)
)operator bool (X x)
好的 - 让我们改变
Console.WriteLine(X.M(1, out a));
到
Console.WriteLine(X.M(1, out a) && X.M(2, out b));
现在 - 结果是:
x = 1
in false operator for 1
in bool operator for 1
True
2个问题:
为什么这个in false operator for 1
会执行?我没有看到false
出现在这里的任何理由。
我能理解为什么X.M(1, out a) && X.M(2, out b)
中的正确部分仅在左侧部分为false
时才会执行 - 但我再也看不到左边部分可能是假的。它确实返回true
(根据我的第一个代码)
NB
我已多次阅读帖子中的答案:
乔恩说:第二个&&是正常的&&在两个bool表达式之间 - 因为 Nop返回bool,并且没有&(X,bool)运算符...但是有一个 从X转换为布尔。
所以它更像是:
bool first = X.M(1,out a)&& X.M(2,out b);
if(first&& Nop(a,b))即使只有&&的第一个操作数,现在首先是真的。一直都是 评估......所以b真的没有被分配。
我仍然不明白:"首先是true
(????),即使只有&&的第一个操作数。已被评估"
答案 0 :(得分:5)
首先,不要忘记这是故意奇怪的代码,用于查找角落案例。如果你在真正的程序中找到一个行为类似的类型,找到作者并用它们保密。
我仍然不明白:“首先是真的(????),即使只评估了&&&&&&&&&&&&&&&
是的,因为在操作数不是&&
的情况下处理bool
操作数的方式。它在C#规范的第7.12.2节中规定:
操作
x && y
的评估结果为T.false(x) ? x : T.&(x, y)
,其中T.false(x)
是对operator false
中声明的T
的调用,而T.&(x, y)
是在&
中调用所选运算符。换句话说,首先评估x
并在结果上调用operator false
以确定x
是否肯定是假的。然后,如果x
肯定是假的,则操作的结果是先前为x
计算的值。否则,将对y
进行求值,并对先前为operator &
计算的值和为x
计算的值调用选定的y
,以生成操作的结果。< / p>
所以,按顺序:
X.M(1, out a)
被调用,以获得结果 - 暂时将其称为op1
X.false(op1)
,然后返回true
X.M(1, out a) && X.M(2, out b)
的结果为op1
op1
到bool
的转化价值,然后返回true
。这是由于Console.WriteLine
的重载解析。回答你的具体困惑:
但我再也看不到左边的部分是如何假的。它确实返回true(根据我的第一个代码)
它返回一个有点矛盾的值 - false
运算符返回false
,true
,但true
转换为bool
}返回true
。一旦你理解它是false
运算符返回的值,它确定是否要评估&&
的第二个操作数,它应该都是明确的。