我正在重载&&和代码满足所有要求。
我有两个类:
//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;
运行时发生的情况。
- 类
Four
的重载false
方法被调用,返回True
(基本上意味着false),这意味着operator &
方法不被调用,这是好的。但是你不能分配一个布尔值给hh
,所以我注意到以下几点:
从输出中,我可以看到创建了一些对象,默认值为j
和i
,变量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
我正在超载
&&
还要注意这个语句实际上是不正确的——你没有重载&&
,它是不可重载的:
条件逻辑操作符不能重载。但是,如果具有重载
true
和false
操作符的类型也以某种方式重载&
或|
操作符,则可以对该类型的操作数分别求值&&
或||
操作符。