Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么真一元运算符和假一元运算符需要成对声明?_C#_Operator Overloading_Operators - Fatal编程技术网

C# 为什么真一元运算符和假一元运算符需要成对声明?

C# 为什么真一元运算符和假一元运算符需要成对声明?,c#,operator-overloading,operators,C#,Operator Overloading,Operators,根据C语言规范: true和false一元运算符需要成对声明。如果一个类声明了其中一个运算符而没有声明另一个运算符,则会发生编译时错误 这似乎是一个奇怪的选择,因为这两个运营商尽管名字似乎有关联,但却有着不同的用途 运算符true的完整使用列表: 它允许在if、while、do或语句中使用类型来代替bool,并作为三元的第一个操作数:操作员。(仅当类型没有匹配的隐式转换时相关隐式运算符bool) 如果相同的结构/类以适当的方式重载运算符|,则它也允许使用短路运算符| 操作员false的完整操作列

根据C语言规范:

true
false
一元运算符需要成对声明。如果一个类声明了其中一个运算符而没有声明另一个运算符,则会发生编译时错误

这似乎是一个奇怪的选择,因为这两个运营商尽管名字似乎有关联,但却有着不同的用途

运算符true的完整使用列表

  • 它允许在
    if
    while
    do
    语句中使用类型来代替
    bool
    ,并作为三元
    的第一个操作数:操作员。(仅当类型没有匹配的隐式转换时相关
    隐式运算符bool
  • 如果相同的结构/类以适当的方式重载
    运算符|
    ,则它也允许使用短路运算符
    |
  • 操作员false的完整操作列表:

    • 如果相同的结构/类以适当的方式重载
      运算符&
      ,则它也允许使用短路运算符
      &
    请注意,只有当
    运算符&
    被相同类型重载时,
    运算符false
    才有意义。对于
    if
    while
    等,绝不允许
    运算符为false
    相关。如果要“否定”类型的实例,请重载一元
    运算符(“非”)代替

    因此,在需要
    运算符true
    但不需要
    运算符false
    的情况下,似乎有合法的用法,反之亦然

    例如,如果我只需要使用上面的(1),我会重载
    运算符true
    (也可能是
    运算符!
    )。但是我可能不想重载
    &
    ,因此必须编写
    操作符false
    是没有意义的

    在相反的方向上,我可以设计一种类型,在这种类型中,我可以将
    &
    实例放在一起,并且也可以使用短路
    &
    ,使用(•),因此我会过载
    操作符false
    。但这并不一定意味着我希望我的类型具有
    |
    |
    ,更不用说我要求我的类型在
    if
    while
    中可用

    无需过载
    |
    &
    “成对”

    与实际限制相比,更有用的是指定:

    (假设)如果类或结构重载
    运算符false
    ,而没有匹配的
    运算符的重载&
    ,则会发生编译时错误

    事情是这样的,人们被迫(根据C#spec)编写
    操作符false
    成员,这些成员绝对没有被调用的机会


    问题:要求
    运算符true
    运算符false
    同时进行的动机或历史原因是什么?

    这样做是为了迫使程序员为工作选择合适的工具。如果您认为您正在重载
    运算符false
    ,并且绝对没有被调用的机会,那么您应该重载转换
    运算符bool(T)

    运算符
    true
    false
    主要用于涵盖
    true
    false
    状态重叠的情况,即对象可以同时是
    true
    false
    (或者,它既不能是
    true
    也不能是
    false

    您所描述的情况,即当只需重载
    运算符true(T)
    时,没有匹配的
    运算符false(T)
    ,由不同的机制覆盖-将运算符转换为
    bool
    。如果您只需要从问题中涵盖场景(1),则可以重写
    运算符bool(T)
    ,并在需要
    bool
    的语句中使用类,而无需执行任何其他操作

    当必须重载
    运算符true
    和运算符
    false
    时,会出现一种特殊情况,即:(1)重载
    运算符&
    运算符
    ,以及(2)希望在短路表达式中使用重载运算符。请注意,(1)和(2)都是必需的:当您没有过载
    操作员|
    操作员&
    时,单个
    操作员bool(T)
    就足以短路;在短路上下文中不使用
    运算符|
    运算符&
    的情况也是如此

    在这种情况下,语言设计者有几种选择,其中没有一种看起来特别干净,因为某些单独正确的结构在组合使用时会变成错误

  • 检测
    true
    false
    一起重载
  • 检测用于短路的
    &
    ,是否过载而没有
    false
  • 检测用于短路的
    |
    ,在没有
    true
  • 检测短路上下文中使用的
    true
    ,在没有匹配的
    的情况下过载
  • 检测短路上下文中使用的
    false
    ,在没有匹配
    |
  • 错误2到错误5最糟糕的部分是,导致错误的一个组成部分来自使用类的代码,而不是类本身的代码

    编译器设计人员选择实现选项1、2和3(除了2和3之外,他们要求同时重载
    true
    false
    ,以满足1)。他们本可以选择4号和5号选项,但这不会让它更干净,因为有三种不同的条件