2010-02-05 20 views
9

a bool variable podría contener cierto o falso, mientras que bool? podría ser nulo también.¿Cuál es el uso del tipo Nullable <bool>?

¿Por qué necesitaríamos un tercer valor para bool? Si no es cierto , lo que sea, es == falsa

¿Puede sugerir un escenario en el que me apetece un bool ? en su lugar.

Gracias

+2

Para facilitar su búsqueda, ya que buscar un signo de interrogación en Google es una verdadera perra :) El tipo completo es 'Nullable ' –

+2

No necesita un tercer valor para 'bool', por lo que solo tiene dos. Pero 'bool?' - es decir, 'Nullable ' donde 'T' es' bool' - es una cosa completamente diferente - significa "o este es' nulo', o algún valor del dominio de valor de tipo 'bool'" . –

+0

Esa es la razón por la que SOF no me deja agregar un nuevo bool? ¡¡¡¡etiqueta!!!! –

Respuesta

28

Algo puede ser cierto, falso o indefinido por muchas razones. ¿Cómo podría uno responder "¿Es tu tercer hijo una niña?" si uno solo tiene dos hijos? Tanto verdadero como falso son incorrectos. Nulo sería apropiado para decir que la comparación no se aplica.

+3

O una enumeración es quizás una mejor opción. – kenny

+4

Solo hay una respuesta adecuada a esa pregunta: MU. –

1

ser anulable podría indicar que el bool no se puede establecer o inicializado si eso es algo que su programa podría necesitar saber

3

que podría ser desconocido, además de verdadero o falso .. en la base de datos land a NULL normalmente significa desconocido o ningún valor

3

Lazy programming!

public bool MyProp 
{ 
    get { return (myProp = myProp ?? GetPropValue()).Value; } 
} 
private bool? myProp; 
+0

grossssss! ¡pero fresco! :) – pestilence669

1

Bueno, yo podría ver que está siendo utilizado como un tipo de cosas "no determinado todavía", yo uso Bools todo el tiempo y, a veces sólo dos valores no es bastante !! por ejemplo:

bool? bl; 

bl = true; //Yes 

bl = false; //No 

bl = null; // Not determined, so do nothing 

en mi opinión, es sólo el tercer valor a un bool.

+0

podemos hacer lo mismo para un bool: bool b == null; ??? –

+0

@Asas, bool es un tipo de valor que no admite nulos, bool b = null no se compilará, de ahí la necesidad de bool? (System.Nullable ) –

+0

@ Asad, si intenta hacer algo con un 'bool 'unificado, obtendrá un error' variable no asignada' cuando compile. – jball

0

Desearía usar eso para cubrir la situación de "¿y si el usuario no especifica ni verdadero ni falso?"

Es solo una manera de cubrir todos los resultados posibles.

2

significa un valor nulo

  • No sé.
  • datos suficientes en este momento
  • Se abre el estado del gato antes de que el cuadro de
  • no he tomado una decisión todavía
  • beneficio

significa un valor nulo Mu

5

Es bueno para cuando algo no ha sido respondido aún, piense en un cuestionario. Tiene una lista de preguntas y/n y solo algunas han sido respondidas. No querrá publicar verdadero o falso en la tabla de la base de datos porque el usuario aún no ha respondido la pregunta.

0

Digamos que se ha realizado un pedido pero aún no se ha enviado. ¿Cuál es el valor de Order.ShippedDate?

La antigua manera de manejar esto era usar un valor mágico como DateTime.MinValue. Hubo otras formas de resolver este problema (por ejemplo, un tipo de envoltura o un indicador adicional bool que indica que el pedido aún no se ha enviado). Ninguno de estos es muy satisfactorio. Lo que se necesita es una forma uniforme de manejar el problema de un valor faltante o desconocido.

Por lo que el enfoque moderno es permitir Order.ShippedDate para tomar un valor que semánticamente capta que la orden no se ha enviado todavía. Ese es el papel que juegan los tipos que aceptan nulos. Semanticamente debe pensar en una instancia de Nullable<T> con HasValue siendo false como representando "faltante" o "desconocido".

Además, las bases de datos permiten desde hace mucho tiempo que una columna permita null. Por ejemplo, podría tener una columna de valores enteros que permita null. ¿Cómo interactúas con una columna del código si no permites el nullable int s? Nuevamente, podría usar los enfoques mencionados anteriormente, pero es mucho más agradable cuando el lenguaje tiene una función incorporada para capturar semánticamente la situación que estamos tratando de modelar.

0

Aquí hay otro caso de uso. Piense en una estructura de datos jerárquica que tiene una propiedad booleana. Establecer dicha propiedad en el elemento primario se aplicará a todos sus elementos secundarios, a menos que se establezcan explícitamente. Piense en permisos de solo lectura para archivos y carpetas en Windows (que SI tienen una casilla de verificación de tres estados).

Parent1(readonly: true, evaluates true) 
    |-Parent2(readonly: null, evaluates true) 
    |-Child1(readonly: false, evaluates false) 
    |-Child2(readonly: null, evaluates true) 
|-Parent3(readonly: false, evaluates false) 
    |-Child1(readonly: false, evaluates false) 
    |-Child2(readonly: null, evaluates false) 
0

creo que la motivación principal (al menos que se presentó como esto :-)) para añadir tipos anulables en C# 2 fueron las bases de datos. En la base de datos, cualquier tipo de datos puede tener el valor NULL y al asignarlos a C#, esto es un problema. Los tipos anulables le permiten tratar esto con bastante elegancia: puede usar int?, bool? y otros. Se usan, por ejemplo, en LINQ to SQL.

Qué significa el tercer valor para los booleanos, eso por supuesto depende de la aplicación. Supongo que, por lo general, significará que el valor/campo no está disponible.

11

Varias respuestas discuten la importancia de los tipos de nullable en general. Hay una respuesta adicional para el booleano anulable, específicamente. Es difícil de entender en C#, pero es muy fácil de entender si observas una lógica de valor nulo en cualquier base de datos.

Digamos que está siguiendo una lista o tabla de Shipments. A Shipment tiene un DeliveryDate, pero por supuesto no conoce esta información hasta mucho después de que se haya realizado el envío, y probablemente al menos unos días después de que el envío se entregó realmente, cuando UPS finalmente se pone a notificarlo. Así que, por supuesto, el DeliveryDate es un Nullable<DateTime> (o DateTime?).

Desea recuperar una lista de todos los envíos que se entregaron durante la última semana. Así se escribe esto:

var deliveredThisWeek = shipments.Where(s => 
    s.DeliveryDate >= DateTime.Today.AddDays(-7)); 

Debería incluirse a los envíos con una fecha de entrega null? (La respuesta es, por supuesto, no.)

OK, entonces ¿qué pasa con esto:

var deliveredBeforeThisWeek = shipments.Where(s => 
    s.DeliveryDate < DateTime.Today.AddDays(-7)); 

En caso de envíos con una fecha de entrega null incluirse en estos resultados? La respuesta es todavía no.

Ahora tiene una situación curiosa. Puede pensar que entre las dos consultas, recibirá todos los envíos en el sistema. A | !A es siempre true, ¿verdad? No cuando se trata de nulos.

Incluso éste no puede conseguir que todos los resultados:

var deliveredAnytime = shipments.Where(s => 
    (s.DeliveryDate >= DateTime.Today.AddDays(-7)) || 
    (s.DeliveryDate < DateTime.Today.AddDays(-7))); 

Entonces, ¿cómo es esto posible?

Para representar con exactitud esta lógica, necesita una condición que no sea verdadera o false. Y nuevamente, C# es un mal ejemplo aquí porque no implementa la lógica de la manera en que realmente lo esperaría. Pero en SQLese, tiene sentido, porque:

[DeliveryDate >= BeginningOfWeek] = NULL 
[DeliveryDate < BeginningOfWeek] = NULL 

Claramente, NULL OR NULLNULL sigue siendo, no TRUE. Así es como puede decir correctamente que un envío no se entregó antes del comienzo de la semana, y no se entregó después. O, más exactamente, no sabemos cuando se entregó, por lo que no puede decir con seguridad que hace coincide con cualquiera de esas condiciones.

Pero C# no es tan uniforme. En C#, si el DeliveryDate es nulo, entonces:

(s.DeliveryDate >= beginningOfWeek) == false 
(s.DeliveryDate < endOfWeek) == false 

Qué le consigue la respuesta correcta para nuestra consulta anterior, por lo que podría estar tentado a decir que la lógica booleana regular es lo suficientemente bueno, excepto que éste se mete se todo:

var deliveredThisWeek = shipments.Where(s => 
    !(s.DeliveryDate < DateTime.Today.AddDays(-7)); 

Aha ... ahora nos está devolviendo null fechas de entrega! ¡Esto no está bien! Y antes de que alguien diga "@Aaronaught, ¿en qué estás hablando, por supuesto, ¡esos envíos NO se entregaron antes de la semana pasada, por lo que la condición debería cubrirlos!", detente y piensa en ello por un segundo.

El NULL en realidad no significa que no se entregaron. El NULL significa que no sabemos cuando se entregaron. Es posible que un empleado recoja la confirmación mañana y rellene el DeliveryDate como hace dos semanas, invalidando los datos que acabamos de recoger. Debe no ser instancias nulas que vuelven de esa consulta, y sin embargo existen. Si escribió la misma consulta en SQL, esos resultados se excluirán.

Por lo tanto, ¿Por qué si te importa Nullable<bool> cuando aparentemente C no?Para que pueda evitar caer en esta trampa en su propio código:

public static bool? IsThisWeek(DateTime? dt) 
{ 
    return (dt != null) ? (bool?)(dt.Value > DateTime.Today.AddDays(-7)) : null; 
} 

var deliveredBeforeThisWeek = shipments.Where(s => 
    (!IsThisWeek(s.DeliveryDate) == true)); 

// Or, the equivalent: 
var alsoDeliveredBeforeThisWeek = shipments.Where(s => 
    (IsThisWeek(s.DeliveryDate) == false)); 

Esto es un poco incómodo, pero correcto. Hemos escrito una consulta que más o menos comunica su intención correctamente, y (bool?)null no equivale a trueofalse, por lo que obtenemos los resultados correctos en ambos casos.

Si alguna vez tiene que evaluar una condición en la que la respuesta podría ser "no sé" - usar un bool? (También conocido como Nullable<bool>) como resultado.

De esta manera, la persona que llama puede decidir cómo manejar una respuesta "No sé" en lugar de simplemente elegir una opción predeterminada. Cualquier otra cosa significa que su clase es mintiendo.

2

Lo usé en un valor de filtro. Básicamente tengo un campo bool en la base de datos, pero quería tres estados: solo devuelve filas donde el valor es verdadero, solo devuelve filas donde el valor es falso, no filtra y devuelve todas las filas.

Sin un bool nullable tendría que usar ya sea una enum o un segundo bool para determinar "Filtrar por este campo sí/no", lo que añadiría hinchazón.

0

Si está a punto de usar un bool Nullable, consideraría usar Enum u otra estructura de datos en su lugar. Puede ayudarlo a evitar errores cuando se desconoce el significado de NULL.

Recientemente, he manejado mal un bool Nullable. No entraré en los detalles del error, pero digamos que fue lo suficientemente malo como para requerir una reversión completa. Comencé a preguntarme qué tan práctico es usar en la mayoría de las aplicaciones. (En parte en un intento de aferrarme a mi orgullo roto como resultado del error estúpido)

Luego, me encontré con esta publicación y con la respuesta aceptada por Lee.

Esto parece tener sentido, pero cuanto más tiempo paso con él, la respuesta se vuelve FALSA en la práctica en lugar de NULA. NULL es demasiado confuso.

Antes de responder a esta pregunta, uno debería asignar un significado muy específico a NULL. ¿NULL significa que hubo un error en el cálculo? ¿Qué pasa si hay un error en el cálculo antes de que se determine que solo hay dos hijos? (También diría que si realmente solo hay dos hijos, esto podría manejarse antes de que se plantee la pregunta al programa.)

Porque no sabemos qué significa NULO y definitivamente no es VERDADERO (porque , ¿cómo podría ser?) la MEJOR respuesta es FALSA.

Además, si esta pregunta realmente devuelve NULL, hemos introducido una nueva definición para el dominio. ¿Cuál es el alcance de esta definición?

Parece que los estados VERDADERO o FALSO representan una certeza con respecto a un resultado. NULL se puede concebir en al menos tres estados diferentes. Por ejemplo, la afirmación "Thomas fue al bar anoche".

VERDADERO - Sí, Thomas fue al bar. (respuesta más probable si supiera Thomas) FALSO - No, Thomas no fue al bar. NULL - ¿Huh? Conocible: algo salió mal en el primer cálculo. P.ej. usted le hizo la pregunta a Thomas, pero él estornudó mientras respondía, dejándolo sordo momentáneamente.Simplemente preguntarle de nuevo te dará la respuesta.

Desconocible - El bar se quemó y Thomas se saltó la ciudad. No hay una forma realista de obtener la respuesta. (Por favor, no haga agujeros en esto, pero sé que lo hará)

No aplicable - Consulte el ejemplo anterior con respecto a los tres niños, pero, bares y Thomases en su lugar.

¿Qué significa NULL aquí? La determinación de lo que NULL significa debe realizarse caso por caso. Esta es la razón por la que creo que a menudo es mejor usar un Enum u otra estructura ya que expone con mayor gracia la intención detrás de un valor de retorno no binario.

Cuestiones relacionadas