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

时间:2015-08-14 11:43:41

标签: c#

关注来自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来自XBool的隐式运算符 (所以 - Console.WriteLine将整个表达视为Console.Writeline(bool)
  • 最后一次" True"来自"返回true"在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个问题

  1. 为什么这个in false operator for 1会执行?我没有看到false出现在这里的任何理由。

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

  3. 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(????),即使只有&&的第一个操作数。已被评估"

1 个答案:

答案 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
  • 接下来,调用从op1bool的转化价值,然后返回true。这是由于Console.WriteLine的重载解析。

回答你的具体困惑:

  

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

它返回一个有点矛盾的值 - false运算符返回falsetrue,但true转换为bool }返回true。一旦你理解它是false运算符返回的值,它确定是否要评估&&的第二个操作数,它应该都是明确的。