C# instanceof/is优先级的原因

C# instanceof/is优先级的原因,c#,java,language-theory,C#,Java,Language Theory,在C#/Java和C#/Java中,的操作符优先级分别为instanceof导致一些难看的必要括号。例如,如果(!bar instanceof Foo)您必须编写if(!(bar instanceof Foo)),而不是编写if(!(bar instanceof Foo)) 那么为什么语言团队决定的运算符优先级高于is/instanceof?诚然,在C语言中,你可以覆盖操作符在某些情况下会导致不同的结果,但这些情况似乎非常罕见(在任何情况下都是不直观的),而检查某事物是否不是某事物的类型或子类型

在C#/Java和C#/Java中,
的操作符优先级分别为
instanceof
导致一些难看的必要括号。例如,如果(!bar instanceof Foo)
您必须编写
if(!(bar instanceof Foo))
,而不是编写
if(!(bar instanceof Foo))


那么为什么语言团队决定
的运算符优先级高于is/instanceof?诚然,在C语言中,你可以覆盖
操作符
在某些情况下会导致不同的结果,但这些情况似乎非常罕见(在任何情况下都是不直观的),而检查某事物是否不是某事物的类型或子类型的情况更可能发生

因为通过写入
if(!bar instanceof Foo)
它会对bar求反,然后查找instanceof。因为这是最左边的语句,我不认为instanceof有优先权

然后
如果(!(bar instanceof Foo))
它首先使其成为instanceof,然后否定整个事件


如果您需要否定bar,然后检查,例如,然后执行
(!bar)instanceof Foo)

以下是我对此事的看法,没有权威来源


instanceof
是一个非常大的运算符。大多数运算符最多为两个字符。此外,
instanceof
与变量之间必须有空格。由于这两个独特的特性,当您看到像
这样的表达式时!条形instanceof Foo
,则
instanceof
似乎自然地分开了
!bar
Foo
,如果
,许多人会感到惊讶!bar
不是子表达式


类似的思路也可以应用于
is
,附加的参数是遵循Java已经做过的事情。

在Java中,
instanceof
是其中一个,与其他的具有相同的优先级:

关系表达式:
移位加压
关系表达式<移位表达式
关系表达式>移位表达式
关系表达式=移位表达式
ReferenceType的关系表达式实例
从这个角度来看,这两条线应该遵循相同的结构:

if (!(a instanceof b))
if (!(a < b))
if(!(a实例/b实例))
如果(!(a
阴谋论:

C#设计人员不希望您使用
is
操作符。使用此操作符通常会让人觉得OOP设计很糟糕。如果您发现自己经常使用它,这可能意味着您的类层次结构是错误的,您需要更加依赖虚拟方法和模式。Java设计人员甚至更进一步:他们将操作符命名为
instanceof
,让您每次使用它时都感到畏缩

事实上,这并非不可能。在很多情况下,语言和库设计者会使某些功能难以使用。一些例子:在.NET中的字符编码(您应该始终使用Unicode),在Pascal中的
goto
(您应该避免)等等。有时它是由糟糕的设计(如.NET中的WPF)引起的,但有时它是故意的

  • +
    +
    等基本运算符相比,
    instanceof
    是一个非常长的词。当你们阅读《条件》时,你们只是失去了你们的注意力,至少我是这样
  • 它被空格包围,可以提高可读性,但另一方面,您无法将其与其他操作数连接,例如
    5+6
    可以

  • 我相信大家决定说:好吧,低优先级,所以每个人都必须提供括号来确定发生了什么事,我认为这只是历史。如果我没记错的话,在Java的最初版本中,如果(一个Foo的instanceof | |一个Bar的instanceof)没有括号,你甚至无法编写
    If(一个Foo的instanceof | |一个Bar的instanceof)
    。我认为Java2发生了变化。我不知道他们为什么不把它放在一个更高的优先级上(例如,高于逻辑not)。也许是因为它会干扰typecast操作符,从而破坏兼容性

    C#当时似乎使用了与Java相同的优先级


    我仍然认为,将按位and/or的优先级保持在与逻辑and/or相同的级别也是错误的。如果((x&(FLAG1 | FLAG2))!=0)这样的东西很烦人。

    显然,像
    这样的表达式!SomeType的b instanceof
    (读:“否定
    b
    ,然后检查结果值是否为
    SomeType
    ”)在Java中没有多大意义:

    从逻辑上讲,
    b
    必须是某种布尔对象(这样
    就可以工作了),即使你对它的值求反,它仍然是一个布尔值,与以前的类型相同,那么为什么要一开始就对它求反呢

    (实际上,你甚至不能这样做:
    b
    不能是
    布尔值
    ,因为
    instanceof
    要求它是一个真实的
    对象
    ,但是,如果
    b
    是一个
    布尔值
    !b
    仍然会计算为一个原语
    布尔值
    ,因此
    instanceof
    不起作用。)

    因此,我们可以说
    !SomeType的instanceof
    在Java中没有任何语义意义。因此,我们可以将其含义重新指定为“检查
    b
    是否不是
    SomeType
    ”我们可以吗

    考虑到这本可以在语义上进行更改,但仍然没有完成,这让我得出结论,这并不是故意的,但对于
    instanceof
    ,有一个更实际的理由使用较低的优先级:

    如果你给instanceof的优先级高于一元运算符
    ,我会怀疑解析会变得复杂。你可能想检查一下

    另一方面,如果
    !SomeType
    的实例意味着“检查
    b
    是否不是
    SomeType
    ”类型,这仍然会诱使新手程序员认为
    -1 ** 2 == -(1 ** 2)  # true
    
    False is (not None)   # false
    
    False is not None     # true