C#重载短路&&运算符时短路场景返回对象生成机制疑问
C# 重载
&&运算符的短路返回逻辑解答 核心规则说明
C# 不允许直接重载&&运算符,通过重载operator true、operator false和operator &让自定义类型支持&&运算的写法符合语法要求,编译器会按照如下固定规则生成x && y的执行逻辑:
- 首先调用
operator false(x)判断第一个操作数的逻辑值:- 如果返回
true(即x逻辑为假),触发短路:直接将x作为整个&&表达式的结果返回,不会执行y的求值,也不会调用operator &方法。 - 如果返回
false(即x逻辑为真),才会对y求值,再调用operator &(x, y),将方法返回值作为整个&&表达式的结果。
- 如果返回
疑问解答
1. &&重载规则的认知遗漏
存在两个关键认知偏差:
- 错误认为短路判断时会产生
bool类型的返回值:实际上operator false返回的bool仅用于分支判断,不是&&表达式的返回值。只要实现的operator &返回类型是Four,编译器生成的&&运算符返回类型就固定为Four,全程不会出现bool转Four的需求。 - 不知道短路分支的返回值就是第一个操作数本身:默认短路时会生成新的结果对象,实际上该分支没有任何新对象创建逻辑,直接返回已存在的第一个操作数。
2. 所谓"默认值对象"的真实来源
不存在"短路时自动创建结果类型对象"的逻辑:
- 观察到的j、i字段均为0的
Four实例,就是代码第一行通过Four f1 = new();创建的第一个实例。该实例调用无参构造时没有给j、i两个int类型字段赋值,值类型字段默认值就是0,和观察到的字段值完全吻合。 - 无参构造中的打印语句只会输出2次,分别对应f1、f2两个实例的初始化,
hh只是持有了f1的引用,没有触发任何构造函数调用,自然不会打印第三次vvvvvvv。
可以在现有代码中加一行做验证:
Console.WriteLine(object.ReferenceEquals(hh, f1));
运行后会输出True,直接证明hh和f1是同一个对象实例,全程没有新对象被隐式创建。
内容的提问来源于stack exchange,提问作者Erik_JI
相关产品推荐
相关产品推荐

