在 C# 中重载短路 && 运算符时出现问题

  • 本文关键字:问题 运算符 重载 短路 c#
  • 更新时间 :
  • 英文 :


我正在重载&&和代码满足所有要求。

我有两个类:

//the class with the Main method
Four f1 = new();
Four f2 = new();
Four hh = f1 && f2;
Console.WriteLine(hh.j + "    "+hh.i);
class Four {
public int j, i;
public Four() {
Console.WriteLine("vvvvvvv");
}
public Four(int o, int h) {
j = o;
i = h;
}
public Four(int h) {
i = h;
}
public static bool operator true(Four c) {
return (c.j!=0||c.i!=0)?true:false;
}
public static bool operator false(Four c) {
return (c.j == 0 && c.i == 0) ? true : false;
}
public static Four operator &(Four j, Four h) {
return (h.j != 0 && h.i != 0) & (j.j != 0 && j.i != 0) ? new Four(1, 1) : new Four(2, 2);
}
}

根据我的理解,这是Four hh = f1 && f2;运行时发生的情况。

  1. Four的重载false方法被调用,返回True(基本上意味着false),这意味着operator &方法不被调用,这是好的。但是你不能分配一个布尔值给hh,所以我注意到以下几点:

从输出中,我可以看到创建了一些对象,默认值为ji,变量hh指向该对象。

我不明白这个对象是如何被创建的。你能告诉我我错过了什么吗?这是否意味着,如果第一个操作数决定操作的结果(在本例中确实如此),则创建一个相同类型的新对象?(如果是,我不明白它是如何创建的,因为没有调用无参数构造函数,因为构造函数中的语句从未被打印。)

这里没有创建新对象,hh指向f1引用的已经创建的实例

自定义条件逻辑运算符(&&||)的语言规范:

操作x && y被计算为T.false(x) ? x : T.&(x, y),其中T.false(x)是对T中声明的operator false的调用,T.&(x, y)是对选中的operator &的调用。换句话说,首先计算x,然后在结果上调用operator false,以确定x是否绝对为假。然后,如果x确定为false,则操作的结果是先前为x计算的值。否则,y评估,选择调用operator &x之前计算值和计算值y生产操作的结果。

因此,如果f1的计算结果是false,它将被分配给hh。在赋值后添加Console.WriteLine(object.ReferenceEquals(hh, f1));,你会看到它将打印True:

Four f1 = new();
Four f2 = new();
Four hh = f1 && f2;
Console.WriteLine(object.ReferenceEquals(hh, f1)); // prints True
Console.WriteLine(hh.j + " " + hh.i); // prints 0 0 cause hh is the same instance as f1

我正在超载&&

还要注意这个语句实际上是不正确的——你没有重载&&,它是不可重载的:

条件逻辑操作符不能重载。但是,如果具有重载truefalse操作符的类型也以某种方式重载&|操作符,则可以对该类型的操作数分别求值&&||操作符。

最新更新