online mejor cual convertir c# java language-theory

c# - mejor - Razón de la precedencia de instanceof/is



java vs c# 2018 (9)

Tanto en C # / Java, la precedencia del operador is respectivamente, instanceof conduce a algunos paréntesis feos necesarios. Por ejemplo, en lugar de escribir if (!bar instanceof Foo) tienes que escribir if (!(bar instanceof Foo)) .

Entonces, ¿por qué los equipos de idiomas decidieron eso ! tiene una precedencia de operador más alta que es / instanceof? Es cierto que en C # se puede sobrescribir el operator! lo que llevaría a un resultado diferente en algunas situaciones, pero esas situaciones parecen extremadamente raras (y en cualquier caso no intuitivas), mientras que el caso de verificar si algo no es un tipo o subtipo de algo es mucho más probable.


  1. instanceof es una palabra muy larga en comparación con operadores básicos como + o ++ . Cuando lees condición, acabas de perder tu enfoque, al menos yo lo hago.
  2. Está rodeado de espacios que pueden aumentar la legibilidad pero, por otro lado, no puede conectarse con otros operandos, por ejemplo, como 5+6 puede hacer.

Creo que los muchachos decidieron decir: ok, una prioridad más baja, así que todos deben proporcionar paréntesis para estar seguros de lo que está pasando


Aquí están mis pensamientos sobre el asunto sin una fuente autorizada.

instanceof es un operador muy grande. La mayoría de los operadores son dos personajes como máximo. Además, instanceof debe tener espacios en blanco entre él y una variable. Debido a estas dos cosas únicas, cuando miras una expresión como !bar instanceof Foo , la instanceof parece separar naturalmente a !bar y Foo , y muchas personas encontrarían sorprendente si !bar no era una subexpresión.

Se pueden aplicar líneas de pensamiento similares a, con el argumento adicional de solo seguir lo que Java ya hizo.


Creo que es simplemente histórico. Si recuerdo correctamente en las primeras versiones de Java, ni siquiera podrías escribir if(a instanceof Foo || a instanceof Bar) sin paréntesis. Creo que hubo un cambio en Java 2. No sé por qué no lo pusieron en una prioridad más alta (por ejemplo, más alto que lo lógico). ¿Tal vez porque interferiría con el operador de la transmisión tipográfica y por lo tanto rompería la compatibilidad?

C # parece haber usado la misma precedencia que Java entonces.

Todavía creo que también es un error mantener la precedencia de bit a bit y / o en el mismo nivel que el lógico y / o. Tener que escribir cosas como if( (x&(FLAG1|FLAG2)) != 0) … es molesto.


En Java, instanceof es uno de los operadores relacionales y tiene la misma prioridad que los otros:

RelationalExpression: ShiftExpression RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ReferenceType

Desde esa perspectiva, tiene sentido que esas dos líneas sigan la misma estructura:

if (!(a instanceof b)) if (!(a < b))


Obviamente, una expresión como !b instanceof SomeType (lea: "negate b , luego verifique si el valor resultante es de Type SomeType ") no tiene mucho sentido en Java:

Lógicamente, b tenía que ser algún tipo de objeto booleano (para que funcione ! ) E incluso si negaba su valor, seguiría siendo un valor booleano, del mismo tipo que antes, ¿por qué molestarse en negarlo en primer lugar?

(En realidad, ni siquiera puedes hacerlo: b no puede ser un boolean , porque instanceof requiere que sea un Object real, pero, de nuevo, si b es un Boolean !b aún se evaluaría como un boolean primitivo, por lo que instanceof no funciona.)

Por lo tanto, podemos decir que !b instanceof SomeType no tiene ningún significado semántico en Java. Entonces, podríamos reasignar su significado a "verificar si b no es del tipo SomeType ", ¿no es así?

Dado que esto podría haber cambiado semánticamente y aún no se hizo, me deja con la conclusión de que esto no fue realmente intencional, pero hubo una razón más pragmática para ir con la precedencia más baja, por instanceof :

Desde lo alto de mi cabeza, ¡sospecharía que el análisis se complica si le das una mayor prioridad que el operador único ! . Es posible que desee comprobar eso.

Por otro lado, si !b instanceof SomeType significaría "verificar si b no es del tipo SomeType ", ¡esto aún podría engañar a los programadores novatos para que piensen eso ! opera en b cuando, de hecho, niega el resultado de instanceof , por lo que es menos ambiguo dejar !b instanceof SomeType esencialmente indefinido.


Porque el lenguaje de programación C se equivocó, y Java siguió ciegamente a C.

Cía, ! y ~ son la misma precedencia. En realidad, no importa mucho en C en la práctica porque uno escribe a <b en lugar de! (A> = b).

Pero no hay ninguna instancia de operador.

También puede preguntar por qué / * / * * / * / no se anidan correctamente. O por qué Java cuenta desde 0. O por qué debe haber una palabra clave nula. O por qué Java usa la horrible notación {{} {}} en lugar de endif (o fi). Todo es legado de C.

Y tal vez por una buena razón. Los programadores de C argumentarán que todas estas cosas son el enfoque correcto, porque es a lo que están acostumbrados. Y el primer trabajo de Java fue ser notado y utilizado, a diferencia de muchos otros lenguajes de programación olvidados.

Estar agradecido de que Java no tiene cadenas terminadas en nulo.


Porque escribiendo if (!bar instanceof Foo) niega la barra y luego busca instanceof. porque esta es la declaración más a la izquierda y no creo que instanceof tenga precedencia

entonces if (!(bar instanceof Foo)) lo hace instanceof primero y luego lo niega todo.

si necesita negar la barra y luego verificar, por ejemplo, haga ((!bar) instanceof Foo)


Teoría de la conspiración:

Los diseñadores de C # no quieren que uses is operador . El uso de este operador suele ser un olor a mal diseño OOP. Si lo usa a menudo, probablemente signifique que su jerarquía de clases es incorrecta y que necesita confiar en métodos y patrones virtuales en mayor medida. Los diseñadores de Java fueron aún más lejos: nombraron al operador instanceof para hacer que se estremezca cada vez que lo use.

Esto no es improbable en realidad. Hay muchos casos en los que los diseñadores de idiomas y bibliotecas hacen que algunas características sean inconvenientes de usar. Algunos ejemplos: codificaciones de caracteres en .NET (siempre debe usar Unicode), goto en Pascal (debe evitarlo), etc. A veces es causado por un mal diseño (como WPF en .NET), pero a veces es intencional.


instanceof es un operador binario. ! Es un operador unario.

¡Sería muy confuso, por instanceof unir más estrechamente que ! .
Un ejemplo clásico de la confusión es ** y - en Python, donde tenemos:

-1 ** 2 == -(1 ** 2) # true

No sé sobre ti, pero esto me parece ridículo en Python, así que me alegro de que no estén haciendo lo mismo en Java.

Otro ejemplo de Python es:

False is (not None) # false

y

False is not None # true

lo que creo que es igual de confuso, esta vez porque is y is not son diferentes operadores.