Me gustaría evitar un mayor procesamiento en un objeto si es nulo.
En el siguiente código verifico si el objeto es nulo por cualquiera de los dos:
if (!data.Equals(null))
y
if (data != null)
Sin embargo, recibo un NullReferenceExceptionat dataList.Add(data). Si el objeto era nulo, ¡nunca debería haber ingresado en la ifdeclaración!
Por lo tanto, pregunto si esta es la forma correcta de verificar si un objeto es nulo:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
Si esta es la forma correcta de verificar si el objeto es nulo, ¿qué estoy haciendo mal (¿cómo puedo evitar un mayor procesamiento en el objeto para evitar la NullReferenceException)?
c#
null
nullreferenceexception
desarrollador
fuente
fuente

throw e;versusthrow new Exception(e.ToString());!= nullen sus cheques nulos..Equalssiempre lanzará una excepción si el objeto es nulo.throw e;no es mucho mejor.throw;, por otro lado ...e.ToString()producirá una cadena que incluye no solo el mensaje de error, sino también los de todosInnerExceptionsy el seguimiento de la pila. Entonces ese es un tipo de mensaje de excepción muy pesado. Si usted (¡con razón!) Desea preservar esta información y mantenerla donde pertenece, úsela simplementethrow;.Respuestas:
No es
dataesonull, perodataList.Necesitas crear uno con
Aún mejor: como es un campo, hazlo
private. Y si no hay nada que te impida, hazlo tambiénreadonly. Solo una buena práctica.Aparte
La forma correcta de verificar la nulidad es
if(data != null). Este tipo de verificación es omnipresente para los tipos de referencia; inclusoNullable<T>anula el operador de igualdad para ser una forma más conveniente de expresarnullable.HasValuecuando se verifica la nulidad.Si lo haces
if(!data.Equals(null)), obtendrás unNullReferenceExceptionifdata == null. Lo cual es bastante cómico ya que evitar esta excepción fue el objetivo en primer lugar.También estás haciendo esto:
Esto definitivamente no es bueno. Me imagino que lo pones allí solo para que puedas entrar al depurador mientras aún estás dentro del método, en cuyo caso ignora este párrafo. De lo contrario, no atrape excepciones para nada. Y si lo hace, vuelva a lanzarlos usando solo
throw;.fuente
null != data. Poner la constante primero convierte el error tipográfico de boneheadnull = dataen un error del compilador, en lugar de una asignación no intencional. (También funciona para==.)if (data = null)ya hay un error de tiempo de compilación, por lo que incluso si tardó décadas en llegar allí, ya no necesitamos tener cuidado con eso. Incluso los compiladores de C ++ generarán fácilmente una advertencia sobre la posible asignación no intencionada de ese código.en C #> 7.0 uso
if (obj is null)...Esto ignorará cualquier == o! = Definido por el objeto (a menos, por supuesto, que desee usarlos ...)
Para uso no nulo
if (obj is object)(oif (!(obj is null)))fuente
obj is not null)if (obj aint null):(if (obj is object)C # 6 tiene una comprobación nula monádica :)
antes de:
después:
fuente
result = myObject == null ? null : myObject.SomePropertyy su ejemplo me avisó para escribirresult = myObject?.SomeProperty. ¡¡Hombre!! Eso es astuto. Todavía me encanta codificar ...Su dataList es nula ya que no se ha instanciado, a juzgar por el código que ha publicado.
Tratar:
}
fuente
[Editado para reflejar una pista de @ kelton52]
La manera más simple es hacer
object.ReferenceEquals(null, data)Como
(null==data)NO se garantiza que funcione:Produce:
fuente
No, deberías estar usando
!=. Sidatarealmente es nulo, entonces su programa simplemente se bloqueará con unNullReferenceExceptioncomo resultado de intentar activar elEqualsmétodonull. También tenga en cuenta que, si desea verificar específicamente la igualdad de referencia, debe usar elObject.ReferenceEqualsmétodo ya que nunca sabe cómoEqualsse ha implementado.Su programa se bloquea porque
dataListes nulo ya que nunca lo inicializa.fuente
El problema en este caso no
dataes que sea nulo. Es que endataListsí mismo es nulo.En el lugar donde declara
dataList, debe crear un nuevoListobjeto y asignarlo a la variable.fuente
Además de la respuesta de @Jose Ortega , es mejor usar el método de extensión
Y use el
IsNullmétodo para todos los objetos como:fuente
return T == null ? true : false;y no soloreturn T == null;?A partir de C # 8 , puede usar el patrón de propiedad 'vacío' (con coincidencia de patrones ) para asegurarse de que un objeto no sea nulo:
Este enfoque significa " si el objeto hace referencia a una instancia de algo " (es decir, no es nulo).
Se puede pensar en esto como lo opuesto a:
if (obj is null).... que devolverá verdadero cuando el objeto no haga referencia a una instancia de algo.Para obtener más información sobre patrones en C # 8.0, lea aquí .
fuente
A partir de C # 9 puedes hacer
Para uso no nulo
Si necesita anular este comportamiento, use
==y en!=consecuencia.fuente
Jeffrey L Whitledge tiene razón. Su `dataList´-Object en sí mismo es nulo.
También hay otro problema con su código: está utilizando la palabra clave ref, lo que significa que los datos del argumento no pueden ser nulos. El MSDN dice:
Tampoco es una buena idea usar genéricos con el tipo `Objeto´. Los genéricos deben evitar el boxeo / desempaquetado y también garantizar la seguridad del tipo. Si desea un tipo común, haga que su método sea genérico. Finalmente su código debería verse así:
fuente
Como otros ya han señalado, no lo es,
datapero es muy probabledataListque así seanull. Además de eso...catch-throwEs un antipatrón que casi siempre me da ganas de vomitar cada vez que lo veo. Imagina que algo sale mal en algo quedoOtherStuff()llama. Todo lo que se obtiene es unExceptionobjeto, lanzado en elthrowenAddData(). Sin seguimiento de la pila, sin información de llamadas, sin estado, nada en absoluto para indicar la fuente real del problema, a menos que entre y cambie su depurador para interrumpir la excepción lanzada en lugar de la excepción no controlada. Si tienes que coger una excepción y sólo re-lanzando que de ninguna manera , sobre todo si el código en el bloque try es de ninguna manera no trivial, hacer usted mismo (y sus colegas, presente y futuro) un favor y echar un vistazo a la totalidadtry-catchbloque . Concedido,throw;es mejor que las alternativas, pero todavía te estás dando a ti mismo (o a quien sea que esté tratando de corregir un error en el código) dolores de cabeza completamente innecesarios. Esto no quiere decir que try-catch-throw sea necesariamente malo per se, siempre que haga algo relevante con el objeto de excepción que se arrojó dentro del bloque catch.Luego están los posibles problemas de la captura
Exceptionen primer lugar, pero ese es otro asunto, particularmente porque en este caso particular lanzas una excepción.Otra cosa que me parece más que un poco peligrosa es que
datapotencialmente podría cambiar el valor durante la ejecución de la función, ya que está pasando por referencia. Por lo tanto, la verificación nula puede pasar, pero antes de que el código haga algo con el valor, cambia, quizás anull. No estoy seguro de si esto es una preocupación o no (puede que no lo sea), pero parece que vale la pena tenerlo en cuenta.fuente
utilizar:
Uso condicional:
Actualización (otra forma) actualizada 31/08/2017. Gracias por el comentario.
fuente
cond ? true : false;es completamente equivalente a solocond. Esto no agrega nada.return T == null;también devuelve un booleano!return T == null ? true : false;solo usarreturn T == null;.Siempre que esté creando objetos de clase, debe verificar si el objeto es nulo o no utilizando el siguiente código.
Ejemplo: object1 es objeto de clase
fuente
Simplemente seguí un método que generalmente seguiríamos en Java Script. Para convertir objetos en cadenas y luego verificar si son nulos.
fuente
Lo hice más simple (forma positiva) y parece funcionar bien.
Dado que cualquier tipo de "objeto" es al menos un objeto
fuente