根据 C#语言规范:
true
和false
一元运算符需要成对声明。如果类声明其中一个运算符而不声明另一个运算符,则会发生编译时错误。
这似乎是一个奇怪的选择,因为这两个操作员,尽管看起来有相关的名字,但却有不同的用途。
operator true
的完整使用清单:
bool
,if
,while
或do
语句中使用该类型而不是for
,并作为第一个三元? :
运算符的操作数。 (仅当类型不具有匹配的隐式转换implicit operator bool
时才相关。)operator |
,它也允许使用短路运算符||
。 operator false
的{{3}}完整列表:
operator &
,它也允许使用短路运算符&&
。请注意,如果operator false
被相同类型重载,则operator &
仅 。 operator false
,if
等永远不会while
相关。如果您想“否定”您的类型的实例,请改为重载一元operator !
(“不是”)。
因此,您需要operator true
而非operator false
似乎有合法用途,反之亦然。
例如,如果我只需要使用上面的(1),我会重载operator true
(以及可能operator !
)。但我可能不想重载&
,因此必须编写operator false
毫无意义。
在相反的方向上,我可以设计一种类型,我可以将&
个实例放在一起,也可以使用短路&&
,使用(•),所以我会重载operator false
。但这并不一定意味着我希望我的类型有|
和||
,更不用说我要求我的类型可以在if
,while
等内使用。
无需重复|
和&
“成对”。
而不是实际限制,指定:
会更有用(假设)如果类或结构超载
operator false
而没有operator &
的匹配重载,则会发生编译时错误。
事情的方式,人们被迫(通过C#规范)编写operator false
成员,这些成员绝对没有被调用的机会。
问题:要求operator true
和operator false
一起去的动机或历史原因是什么?
答案 0 :(得分:0)
这样做是为了迫使程序员为作业选择合适的工具。如果您认为自己超载operator false
并且完全没有机会被调用,那么您可能应该重新转换转化operator bool(T)
。
运营商true
和false
在很大程度上涵盖true
和false
州重叠的情况,即对象可以是true
和false
同时(或者,它既不是true
也不是false
)。
您描述的情况,即只有operator true(T)
需要重载但没有匹配的operator false(T)
的情况,由不同的机制 - 转换运算符bool
涵盖。如果您只需要覆盖问题中的方案(1),则可以覆盖operator bool(T)
,并在需要bool
的语句中使用您的类,而无需执行任何其他操作。
有一种特殊情况,您必须重载operator true
和运算符false
- 即,当您(1)重载operator &
或operator |
时,以及(2)您希望在短路表达式中使用重载运算符。请注意,(1)和(2)都是必需的:当您不重载operator |
或operator &
时,单个operator bool(T)
就足以进行短路;在短路环境中不使用operator |
或operator &
的情况也是如此。
在这种情况下,语言设计者有几种选择,其中没有一种看起来特别干净,因为在组合中使用时,某些正确的构造会成为错误。
true
和false
一起超载&
在没有false
的情况下超载|
在没有true
的情况下超载true
是否超载而没有匹配的&
false
是否超载而没有匹配的|
关于错误2到5的最糟糕的部分是错误的一个组成部分来自使用您的类的代码,而不是来自类本身的代码。
编译器设计人员选择实现选项1,2和3(除了2和3之外,他们需要重载true
和false
以满足1)。他们可以选择选项4和5,但它不会使它更清洁,因为无论如何都需要检查三个不同的条件,其中一个是你无法控制的。
最后,他们选择了对称性,隐含地假设如果你将true
和false
重载用于短路&
的上下文,你可能也会这么做支持|
,反之亦然。