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 NullReferenceException
at dataList.Add(data)
. Si el objeto era nulo, ¡nunca debería haber ingresado en la if
declaració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());
!= null
en sus cheques nulos..Equals
siempre 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 todosInnerExceptions
y 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
data
esonull
, 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.HasValue
cuando se verifica la nulidad.Si lo haces
if(!data.Equals(null))
, obtendrás unNullReferenceException
ifdata == 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 = data
en 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.SomeProperty
y 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
!=
. Sidata
realmente es nulo, entonces su programa simplemente se bloqueará con unNullReferenceException
como resultado de intentar activar elEquals
métodonull
. También tenga en cuenta que, si desea verificar específicamente la igualdad de referencia, debe usar elObject.ReferenceEquals
método ya que nunca sabe cómoEquals
se ha implementado.Su programa se bloquea porque
dataList
es nulo ya que nunca lo inicializa.fuente
El problema en este caso no
data
es que sea nulo. Es que endataList
sí mismo es nulo.En el lugar donde declara
dataList
, debe crear un nuevoList
objeto 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
IsNull
mé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,
data
pero es muy probabledataList
que así seanull
. Además de eso...catch
-throw
Es 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 unException
objeto, lanzado en elthrow
enAddData()
. 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
-catch
bloque . 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
Exception
en 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
data
potencialmente 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