2012-09-17 16 views
26

Tengo un compañero de trabajo que es un fan de escribir sus cheques nulos de la siguiente manera:¿Es la "mejor práctica de ReferenceEquals (myObject, null) que" myObject == null "?

if (!ReferenceEquals(myObject, null)) 

que, por el contrario, parece que este sintaxis engorroso para leer y prefieren:

if (myObject != null) 

I He encontrado algunos artículos y preguntas sobre el desbordamiento de la pila discutiendo los méritos de ReferenceEquals con respecto a la sobrecarga del operador, pero fuera del escenario de sobrecarga del operador, ¿hay algún beneficio para ReferenceEquals vs ==?

+2

pena señalar que la versión de su amigo es menos legible (que se convierte en un problema cuando los controles son intercambiables, que se por lo general son). – keyser

+0

Además, es peor que lo anterior, debe escribir 'if (! Object.ReferenceEquals (myObject, null))', por lo que es incluso más largo de lo que se describe en la realidad. –

+1

@ReedCopsey No, no tiene que escribir eso, porque su método está dentro de una clase o estructura que hereda el método estático 'ReferenceEquals' de su clase base (directa o indirecta)' System.Object'. Así que está bien escribir lo anterior (ocultar el método heredado con un método 'nuevo' podría por supuesto suceder, pero esa es una excepción malvada). –

Respuesta

27

pero fuera del escenario de sobrecarga del operador, ¿hay algún beneficio para ReferenceEquals vs ==?

n - la única ventaja (y yo diría que no es mucho de una ventaja) a utilizar de forma explícita Object.ReferenceEquals sería que nunca va a utilizar el operador sobrecargado es igual. En el caso sin sobrecarga, el == Operator se define como "devuelve verdadero si sus dos operandos se refieren al mismo objeto" para todos los "tipos de referencia que no sean cadenas". Como tal, es equivalente (siempre que no esté sobrecargado).

Yo, personalmente, también estoy a favor de usar la segunda sintaxis, y la encuentro más fácil de mantener para la comprobación nula. También argumentaría que cualquier operator== sobrecargado también debería proporcionar una verificación adecuada contra null, y en el caso de que no lo hiciera por alguna razón (lo que sería extraño), probablemente existiría una razón de ser específica detrás de esa decisión que podría causarle querer usar la sobrecarga, no ReferenceEquals.

3

Bueno, si alguien fuera a anular los operadores == o! = Podrían hacer que hagan lo que quieran. Incluso podría tener que hacer algo real como return true; o return false;. Además, si hay un operador sobrecargado, existe la posibilidad de que no funcione tan bien como ReferenceEquals (no se garantiza, y probablemente no sea suficiente, pero aún así).

Dicho esto, dado que con cualquier implementación sensata de cualquier operador sobrecargado, es poco probable que esto sea un problema. Personalmente no uso ReferenceEquals a menos que tenga un motivo convincente para no usar el operador == para ese tipo o en esa instancia en particular.

+5

Si el operador '==' sobrecargado se implementa mal/incorrectamente, entonces * ese es * el error que debe corregirse. Eludirlo utilizando 'ReferenceEquals()' no es el camino correcto. –

+3

@MichaelBurr Estás asumiendo que tienes control sobre el tipo y, por lo tanto, tienes la capacidad de solucionarlo. Ese no es siempre el caso. – Servy

1

En términos de controles nulos, los dos siempre deben devolver los mismos resultados. Si una referencia no nula alguna vez es igual a nula (incluso cuando se utiliza el patrón Objeto nulo), independientemente de si se utilizó ReferenceEquals o el operador ==, es muy algo malo. Entonces, en ese escenario, usaría == /! =.

Yo diría que, si se sobrecarga el operador ==, utilizando ReferenceEquals podría ser ligeramente más rápido. Lo primero que debería hacer un sobrecargado == es ver si las dos variables apuntan al mismo objeto, por lo que en el caso de un operador sobrecargado, usted termina con un marco extra en la pila de llamadas. El uso de ReferenceEquals también garantiza que se haya realizado la única realizada.

En general, también usaría == /! = En casi cualquier otro escenario. La idea completa es que el operador define "igualdad"; eso no siempre es referencial (de hecho, la mayoría de los objetos compuestos deben compararse estructuralmente para la igualdad, son iguales si sus miembros son iguales).El objeto, en teoría, sabe cuál es la mejor manera de compararse con otro objeto, por igualdad, orden relativo, etc. y así, en lugar de codificar una pieza de lógica muy específica y posiblemente incorrecta, debe usar la naturaleza orientada a objetos del lenguaje para deja que el objeto te diga si es igual a cualquier otra cosa o no.

0

La etiqueta VB.NET probablemente no debería haber sido incluida en esta pregunta ya que no se menciona, pero, para completar, Is es equivalente a Object.ReferenceEquals y siempre se puede usar en lugar de esa llamada.

0

ReferenciaEquals podría ser un poco más rápido. Como se mencionó anteriormente, se asegura de que no se llame a ningún operador Equals sobrecargado. Además, ReferenceEquals asegura que solo se realiza una comparación en lugar de posiblemente 2, dependiendo de la implementación del operador Equals sobrecargado. Aunque es muy probable que el operador sobrecargado esté utilizando ReferenceEquals como la primera declaración.

Yo personalmente uso ReferenceEquals, pero solo en lugares donde realmente estoy retocando para exprimir los últimos ciclos de reloj (lugares que posiblemente se llaman millones de veces por segundo). O cuando no tengo control sobre el tipo, como en el caso de los genéricos. ... Pero nuevamente solo cuando el rendimiento es realmente crítico.

+2

Tenga en cuenta que los operadores no son virtuales. Es el * tipo de tiempo de compilación * lo que importa, no el tipo de tiempo de ejecución. En el caso de los genéricos, a menos que exista una restricción para un tipo que sobrecarga el operador '==', el uso de '==' siempre dará como resultado que se use la sobrecarga 'object', que no debe hacer ningún control y simplemente llamadas 'ReferenceEquals'. En esos casos, no solo será funcionalmente equivalente, sino que el rendimiento será prácticamente idéntico también. Esto hace que los genéricos sean uno de los tiempos * más seguros * para usar '==' en lugar de 'ReferenceEquals'. – Servy

6

con C# 7, puede utilizar:

if (!(myObject is null)) 

Es equivalente a

if (!ReferenceEquals(myObject, null)) 
Cuestiones relacionadas