Está escribiendo una expresión booleana que podría verse así:
team.Category == "A Team" && team?.Manager?.IsVietnamVet
public class Manager
{
public bool IsVietnamVet { get; set; }
}
public class Team
{
public string Category { get; set; }
public Manager Manager { get; set; }
}
... y obtienes un error:
El operador '&&' no se puede aplicar a operandos de tipo 'bool' y 'bool?'
¿Cuál es la forma óptima / más limpia de manejarlo?
team.Category == "A Team" && (team?.Manager?.IsVietnamVet ?? false)¿Es eso realmente legible?
team.Category == "A Team" && (team?.Manager?.IsVietnamVet).GetValueOrDefault()Es posible que no funcione en LINQ-to-Entities ...
team.Category == "A Team" && team?.Manager?.IsVietnamVet == true¿Realmente escribirías
if (condition == true)sin dudarlo?
¿Hay más opciones? ¿Es finalmente mejor escribir:
team.Category == "A Team" && team.Manager != null && team.Manager.IsVietnamVet

team.Manager?.IsVietnamVet, es decir, no condicional nula despuésteam, ya que ya no puede sernull.nullableBool == truebásicamente está probandonullableBool != false && nullableBool != null(y es esta segunda parte la que lo hace útil y, por lo tanto, no superfluo)nullableBool == truesi no creo un contenedor. Es legible porque normalmente no escribe== truecuando usa booleano regular como menciona @Flater, por lo que sugiere que la variable es anulable. Además, mejora la legibilidad de LINQ porque no utiliza múltiples condiciones nulas como menciona @Fabio.Respuestas:
En este caso particular, podría ser prudente seguir la Ley de Deméter, es decir
En términos más generales, si una expresión booleana es compleja o fea, entonces no hay nada que decir que no podría dividirla (o parte de ella) en una declaración separada:
Al recorrer el código en el depurador, a menudo es mejor tener condiciones elaboradas agrupadas en una sola
boolpara ahorrar un poco de desplazamiento del mouse; de hecho, podría ser mejor poner todo en unaboolvariable.o con LINQ:
fuente
a && b && c &&...se ejecutan secuencialmente, y el siguiente ni siquiera se ejecuta si el anterior lo esfalse. Entonces la gente suele poner más rápido al principio. Tenga esto en cuenta cuando mueva cosas a un bool-var separadoIsManagerVietnamVetpropiedad va a registrarse en una base de datos;)Creo que la opción 3 (es decir
== true) es la forma más limpia de probar quebool?estrue, porque es muy claro acerca de lo que hace.En la mayoría de los códigos
x == trueno tiene sentido, porque es lo mismox, pero eso no se aplica aquí, así que creo== trueque no sería muy confuso.fuente
a?.b == trueque estará confundido, pero una vez que comprende lo que está haciendo, se convierte en un idioma muy legible, mucho más agradable que tener que probar!= nullen medio de una expresión compleja. Lo mismo paraa?.b ?? false, que parece haber ganado tracción como la solución más popular, porque coincide con lo que escribiría si estuviera tratando con un tipo que no sea booleano [aunque no me gusta para booleano; para mí, no se lee tan naturalmente; Yo prefiero== true]Ampliando la respuesta de Ben Cottrell, el patrón "Objeto nulo" puede ayudarlo aún más.
En lugar de devolver un
nullequipo / gerente, extraigaITeameIManagerinteractúe y devuelva implementaciones alternativas significativas:Entonces, de repente, puedes hacerlo con
team.ManagedByVietnamVetseguridad.Por supuesto, esto depende de que el proveedor ascendente
teamsea nulo-seguro, pero eso se puede garantizar con las pruebas adecuadas.fuente
Escribí una clase simple que podrías usar:
Si es confiable usar un tipo personalizado, por supuesto. Puedes comparar
MyBoolcon ambosboolyNullable<bool>.fuente