type - En C#, ¿hay una manera limpia de verificar múltiples niveles de referencias nulas?
validar null en c# (8)
¿Hay alguna forma más fácil de formular esta expresión?
Con C # 6, puedes usar el operador condicional nulo ?
.
Ejemplo de código
Este es su código original empaquetado en un método y suponiendo que Sniff()
siempre devuelve true
:
public bool PerformNullCheckVersion1(Person person)
{
if (person != null)
if (person.Head != null)
if (person.Head.Nose != null)
return person.Head.Nose.Sniff();
return false;
}
Este es su código reescrito con el operador condicional nulo C # 6:
public bool PerformNullCheckVersion2(Person person)
{
return person?.Head?.Nose?.Sniff() ?? false;
}
El ??
es el operador de unión nula y no está relacionado con su pregunta.
Para ver el ejemplo completo, consulte: https://github.com/lernkurve/Stackoverflow-question-3701563
Por ejemplo, si quiero llamar a lo siguiente: person.Head.Nose.Sniff()
entonces, si quiero estar seguro, tengo que hacer lo siguiente:
if(person != null)
if(person.Head != null)
if(person.Head.Nose != null)
person.Head.Nose.Sniff();
¿Hay alguna forma más fácil de formular esta expresión?
Aquí hay otra implementación a lo largo de las líneas de la también mencionada Validación de Parámetros Fluentes: cheques nulos encadenados y la mónada Tal vez
En realidad no, ademas
if (person != null && person.Head != null && person.Head.Nose != null)
La mejor forma es usar el operador &&
lugar de anidado if
declaraciones:
if (person != null && person.Head != null && person.Head.Nose != null)
{
person.Head.Nose.Sniff();
}
Tenga en cuenta que técnicamente podría realizar una comprobación nula similar utilizando un árbol de expresiones . Tu método tendría una firma como esta:
static bool IsNotNull<T>(Expression<Func<T>> expression);
... lo que te permitiría escribir código buscando algo como esto:
if (IsNotNull(() => person.Head.Nose))
{
person.Head.Nose.Sniff();
}
Pero esto implicaría una reflexión y, en general, sería mucho más difícil de seguir de una manera profunda en comparación con el método &&
.
Me libraría de cualquier uso de null
y haría algo como esto:
((Nose)person.BodyParts[BodyPart.Nose]).Sniff();
Esto requeriría algún tipo de class
base o interface
.
public abstract class BodyPart
{
public bool IsDecapitated { get; private set; }
public BodyPart(bool isDecapitated)
{
IsDecapitated = isDecapitated;
}
}
Podría usar objetos nulos en lugar de valores nulos. Sniff
no haría nada si los objetos en la cadena de llamadas son objetos nulos.
Esto no arrojaría una excepción:
person.Head.Nose.Sniff();
Sus clases nulas podrían tener este aspecto (también puede usarlas como singletons y tener interfaces para IPerson
, IHead
e INose
):
class NullPerson : Person {
public override Head Head { get { return new NullHead(); }
}
class NullHead : Head {
public override Nose Nose { get { return new NullNose(); }
}
class NullNose : Nose {
public override void Sniff() { /* no-op */ }
}
Como nota al margen, en Oxygene hay un operator para esto:
person:Head:Nose:Sniff;
Primero, puede aprovechar el cortocircuito en los operadores lógicos booleanos y hacer algo como:
if (person != null && person.Head != null && person.Head.Nose != null)
{
person.Head.Nose.Sniff();
}
También tenga en cuenta que lo que está haciendo va en contra de una guía de diseño para el desarrollo de software que se conoce como Ley de Demeter .
Puede utilizar la validación de parámetros fluidos