C# instanceof/is优先级的原因
在C#/Java和C#/Java中,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语言中,你可以覆盖操作符在某些情况下会导致不同的结果,但这些情况似乎非常罕见(在任何情况下都是不直观的),而检查某事物是否不是某事物的类型或子类型
的操作符优先级分别为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