En C # 7 podemos usar
if (x is null) return;
en vez de
if (x == null) return;
¿Hay alguna ventaja en usar la nueva forma (ejemplo anterior) sobre la forma antigua?
¿La semántica es diferente?
¿Es solo cuestión de gustos? Si no, ¿cuándo debo usar uno sobre el otro?
Referencia: Novedades en C # 7.0 .

Respuestas:
Actualización: el compilador de Roslyn se ha actualizado para que el comportamiento de los dos operadores sea el mismo cuando no hay un operador de igualdad sobrecargado . Consulte el código en los resultados del compilador actual (
M1yM2en el código) que muestra lo que sucede cuando no hay un comparador de igualdad sobrecargado. Ambos tienen ahora el==comportamiento de mejor desempeño . Si hay un comparador de igualdad sobrecargado, el código aún difiere .Consulte las versiones anteriores del compilador de Roslyn en el análisis a continuación.
Porque
nullno hay una diferencia con lo que estamos acostumbrados con C # 6. Sin embargo, las cosas se vuelven interesantes cuando cambiasnulla otra constante.Toma esto por ejemplo:
La prueba rinde
a. Si compara eso cono == (object)1lo que hubiera escrito normalmente, hace una gran diferencia.istoma en consideración el tipo al otro lado de la comparación. ¡Esta genial!Creo que el patrón
== nullvs. vs.is nullconstante es algo que es muy familiar 'por accidente', donde la sintaxis delisoperador y el operador igual producen el mismo resultado.Como svick comentó,
is nullllamadasSystem.Object::Equals(object, object)donde==las llamadasceq.IL para
is:IL para
==:Como estamos hablando
null, no hay diferencia ya que esto solo hace una diferencia en las instancias . Esto podría cambiar cuando haya sobrecargado el operador de igualdad.fuente
isllamadasobject.Equals(x, null), mientras se==compila comoceq. Pero el resultado debería ser el mismo, como dijiste.==es un operador sobrecargable. Puede tener cualquier comportamiento que desee con él. Por ejemplo, esto implementado de manera extraña==no le dirá si su instancia es realmente nula.is nullpor otro lado, siempre devolverá verdadero para referencias nulas verdaderas :) Además, si tieneReferenceEqualsen su código, las bombillas VS 2017 sugerirán cambiar ais null, no== null(correctamente).isya no tiene la sobrecarga de una llamada a la función cuando se utiliza para verificar nula. Para prueba, vea el enlace publicado por @svick en los comentarios.Operador igual sobrecargado
De hecho, existe una diferencia en la semántica entre las dos comparaciones cuando se compara
nullcon un tipo que ha sobrecargado al==operador.foo is nullutilizará la comparación de referencia directa para determinar el resultado, mientras quefoo == null, por supuesto, ejecutará el==operador sobrecargado si existe.En este ejemplo, he introducido un "error" en el
==operador sobrecargado , haciendo que siempre arroje una excepción si el segundo argumento esnull:El código IL para
foo is nullutiliza laceqinstrucción para realizar una comparación de referencia directa:El código IL para
foo == nullutiliza una llamada al operador sobrecargado:Entonces, la diferencia es que si lo usa
==, corre el riesgo de ejecutar código de usuario (que potencialmente puede tener problemas inesperados de comportamiento o rendimiento).Restricción de genéricos.
El uso de la
is nullconstrucción restringe el tipo a un tipo de referencia. El compilador asegura esto, lo que significa que no puede usaris nullun tipo de valor. Si tiene un método genérico, no podrá usarlo ais nullmenos que el tipo genérico esté limitado a ser un tipo de referencia.Gracias a David Augusto Villa por señalar esto.
fuente