&&运算符重载和C#中的赋值 - 澄清?

Roy*_*mir 7 c#

下面这个非常有趣的问题, 这是源于这个问题-

我想退后一步 (删除动态环境):

看看这段代码:( 这个的一个变种)

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; }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

x = 1
in bool operator for 1
True
Run Code Online (Sandbox Code Playgroud)

这是理解的:

  • x = 1是从该方法本身(使用Console.Writeline)
  • in bool operator for 1是从隐式运算符XBool (所以 - Console.WriteLine将整个表达式视为Console.Writeline(bool))
  • 最后一个"真实"来自于"返回真实" operator bool (X x)

好的 - 让我们改变吧

Console.WriteLine(X.M(1, out a));
Run Code Online (Sandbox Code Playgroud)

Console.WriteLine(X.M(1, out a) &&  X.M(2, out b));
Run Code Online (Sandbox Code Playgroud)

现在 - 结果是:

x = 1
in false operator for 1
in bool operator for 1
True
Run Code Online (Sandbox Code Playgroud)

2个问题:

  1. 为什么这会in false operator for 1执行?我认为没有理由false在这里出席.

  2. 我能理解为什么正确的部分X.M(1, out a) && X.M(2, out b)只会在左边部分执行时才会执行false- 但我再也看不到左边的部分是如何假的.它确实返回true(根据我的第一个代码)

NB

我已多次阅读帖子的答案:

乔恩说:

第二个&&是两个bool表达式之间的正常&& - 因为Nop返回bool,并且没有&(X,bool)运算符......但是从X转换为bool.

所以它更像是:

bool first = XM(1,out a)&& XM(2,out b);
if(first && Nop(a,b))

现在首先是正确的,即使只评估了&&的第一个操作数...所以b实际上还没有被分配.

我仍然不明白:"首先是true(????),即使只评估了&&的第一个操作数"

Jon*_*eet 5

首先,不要忘记这是故意奇怪的代码,用于找到一个角落案例.如果你在真正的程序中找到一个行为类似的类型,找到作者并用它们一个安静的单词.

我仍然不明白:"首先是真的(????),即使只评估了&&的第一个操作数"

是的,因为在&&操作数不是的情况下处理操作数的方式bool.它在C#规范的7.12.2节中规定:

该操作x && y被评估为T.false(x) ? x : T.&(x, y)在何处T.false(x)调用operator false声明的in T,并且T.&(x, y)是对所选运算符的调用&.换句话说,x首先评估并operator false在结果上调用以确定是否x肯定是假的.然后,如果x肯定是假的,则操作的结果是先前计算的值x.否则,y对其进行求值,并对operator &先前计算x的值和计算的值调用selected ,y以生成操作的结果.

所以,按顺序:

  • X.M(1, out a)被调用,以获得结果 - op1暂时调用它
  • X.false(op1)调用Next ,然后返回true
  • 然后通过以上,表达式的结果X.M(1, out a) && X.M(2, out b)op1
  • 接着,转换的从值op1bool被调用,并返回true.这是由于过载分辨率造成的Console.WriteLine.

回答你的具体困惑:

但我再也看不到左边的部分是如何假的.它确实返回true(根据我的第一个代码)

它返回一个值,这多少有些矛盾-它是false在该false运营商的回报true,但它是true在转化为bool收益true.一旦你理解了它是false运算符返回的值,它确定是否要计算第二个操作数&&,它应该都是清楚的.