2010-12-02 8 views
7

que sólo tiene sentido a veces para comprobar si un objeto no es el tipo de X, por lo que tiene que hacer esto en su lugar:¿Por qué no hay palabra clave "no es" en C#?

if(this.GetType() != typeof(X)) 
{ 
     //Do my thing. 

} 

que es un poco complicado de mi opinión, no sería algo como esto sea más agradable:

if(this is not X) 
{ 
    //Do my thing 
} 
+0

Esos no serían funcionalmente equivalentes si 'X' fuera un subtipo de' this.GetType() '. –

Respuesta

20

¿Y el operador lógico !, se ajusta a la descripción de la palabra 'no' muy bien:

if (!(this is X)) 
{ 
    //Do my thing 
} 

Como aunque otros han señalado, is también se usa para verificar si la clase de un objeto hereda de alguna clase o implementa alguna interfaz, que es bastante diferente de GetType().

Ambos CodeInChaos y StriplingWarrior tienen explicaciones razonables de por qué no hay una palabra clave not en C#.

+1

No necesitaríamos hacer 'not' una palabra clave. Probablemente sería suficiente hacer 'is not' una palabra clave similar a' yield return'. Puede ser un poco confuso ya que la mayoría de los programadores de C# no están acostumbrados a las palabras clave de dos palabras (¿o debería llamarlas frases clave?). Entonces uno tendría que usar 'isnot' que IMO parece feo. – CodesInChaos

+1

Me gustaría ver "!" permitido en algunos casos especiales en C donde tendría un significado claro, pero actualmente no es legal. Un caso estaría fuera del paréntesis para un if, while, etc.(en tales contextos, debe invertir estrictamente la condición, independientemente de las sobrecargas del operador). Otro caso similar podría ser bueno aquí: permita "this! Is x", para evitar paréntesis adicionales. – supercat

4

Uso buen símbolo ol' Bang:

if (!(pero is Human)) 
{ 

} 

Por cierto, is es diferente, ya que capta no sólo la clase derivada de la hoja, pero la jerarquía entera de ello, ambas interfaces y clases.

Así, por

class Human: ICanSpeak, Mamal 
{ 
... 
} 

Human h; 

if (h is Human) { will be true } 
if (h is ICanSpeak) { will be true } 
if (h is Mamal) { will also be true } 
5

Nota que this.GetType()! = typeof(X) devuelve FALSE si este se deriva de (o implementos en caso de un tipo de interfaz), pero no idénticos a X, mientras que this is X vuelve verdadera.

¿Y por qué habría una palabra clave separada cuando puede simplemente usar !(a is X)? Eso está hinchando el idioma con poca ganancia. Como a Eric Lippert le gusta hacer hincapié en que cada nueva característica del lenguaje necesita ofrecer suficientes ventajas para compensar la codificación, la documentación, las pruebas y, por supuesto, la mayor complejidad del lenguaje. Y un operador not is simplemente no ofrece suficiente.

podría implementar un método de extensión, pero creo que eso es estúpido:

public static bool IsNot<T>(this object obj) 
{ 
    return !(obj is T); 
} 
+4

Aparte del hecho de que los métodos de extensión en objetos son una práctica de programación cuestionable, en realidad no es un mal método de extensión. No digo que lo use, pero creo que es bastante razonable. –

+0

@Eric: Realmente deseaba que C# también tuviera un operador que no "no" además de! ¡Uno podría decir que esto es inútil, pero! es realmente difícil de ver/detectar en el código donde "if not (vector.IsNormalized)" es mucho más fácil de analizar visualmente que "if! (vector.IsNormalized)", pero supongo que C# lo hizo de esta manera para no alienar a las personas de C++ , ¿derecho? –

+2

@Eric, ¿puedo preguntar por qué los métodos de extensión de objetos se consideran una mala práctica? – dexter

9

Añadir una palabra clave a un lenguaje añade complejidad. Agregar una palabra clave a un idioma después de la especificación inicial podría causar cambios importantes en la actualización de personas. Por lo tanto, las palabras clave generalmente solo se agregan si hay un caso muy fuerte para ellas. En este caso, como las otras respuestas señalan, es muy fácil de usar el operador de explosión:

if (!(pero is Human)) ... 

... lo que un típico C# (/ C/C++/Java) desarrollador podría leer "si no (pero es humano) ". Entonces no hay mucha justificación para una palabra clave especial.

+1

Por ejemplo, no tenemos la palabra clave 'yield' en C# porque eso hubiera sido un cambio radical. 'yield return x' por otro lado era sintaxis ilegal antes y por lo tanto no hay cambio de ruptura. – CodesInChaos

+1

@CodeInChaos: Sí, pero una palabra clave 'is not' podría caer técnicamente en la misma categoría que' yield return'. La diferencia es que se requiere mucho trabajo para emular el 'rendimiento de retorno', mientras que el operador de bang y los paréntesis son suficientes para emular 'no es '. – StriplingWarrior

+0

Creo que un operador 'isnot' (sin espacios) sería muy fácil y seguro de implementar. Definitivamente votaría para que sea parte de la sintaxis de C#. Tantas veces mientras codificaba rápido, casi lo escribí. Viene muy natural. También tendría intellisense y salvaría todo el bracket y el tipeo del operador de negación. En resumen, hubiera sido útil. – GDS

Cuestiones relacionadas