Что такое использование типа Nullable?

a bool переменная может содержать true или false, в то время как bool? также может быть null.

зачем нам третье значение для bool ? Если это не так true, что бы это ни было, это == false

можете ли вы предложить сценарий, в котором я бы хотел bool? вместо.

спасибо

12 ответов


что-то может быть истинным, ложным или неопределенным по многим причинам. Как бы вы ответили: "ваш третий ребенок-девочка?"если только двое детей? И истина, и ложь неверны. Null было бы уместно сказать, что сравнение не применяется.


различные ответы обсуждают важность нулевых типов в целом. Существует дополнительный ответ для nullable boolean, в частности. Это трудно понять в C#, но очень легко понять, если вы посмотрите на нулевую логику в любой базе данных.

предположим, вы отслеживаете список или таблицу Shipments. А Shipment есть DeliveryDate, но, конечно, вы не знаете эту информацию до тех пор, после отгрузки было сделано, и, вероятно, по крайней мере несколько дней после отгрузка была фактически доставлена, когда UPS, наконец, добирается до уведомления вас. Так что, конечно,DeliveryDate это Nullable<DateTime> (или DateTime?).

вы хотите получить список всех грузов, которые были доставлены в течение последней недели. Итак, вы пишете:

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

должны поставки с null дата доставки будет включена? (Ответ, конечно, нет.)

хорошо, так что об этом:

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

должны пересылки с а null дата доставки быть включены в эти результаты? Ответ еще нет.

Итак, теперь у вас есть любопытная ситуация. Вы можете подумать, что между этими двумя запросами вы получите все поставки в системе. A | !A всегда true, да? Не тогда, когда имеешь дело с нулевыми.

даже этот не может получить все результаты:

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

так как же это возможно?

In чтобы точно представить эту логику, вам нужно условие, которое не является истинным или false. И опять же, C# - это плохой пример, потому что он не реализуйте логику так, как вы действительно ожидаете. Но в SQLese это имеет смысл, потому что:

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

понятно, NULL OR NULL по-прежнему NULL, а не TRUE. Вот как можно правильно сказать, что груз не был доставлен до начала недели,и был не доставлено после. Или, точнее, не знаем!--38-->знаю когда он был доставлен, так что мы не могу смело сказать, что это тут соответствует любому из этих условий.

но C# не так последователен. В C#, если DeliveryDate null, тогда:

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

что дает вам правильный ответ на наш запрос выше, поэтому вы можете поддаться искушению сказать, что обычная логическая логика достаточно хороша, за исключением того, что это все портит вверх:

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

Аха... теперь у нас null сроки поставки! Это неправильно! И прежде чем кто-нибудь скажет "@Aaronaught, о чем вы говорите, конечно, это правильно! Эти поставки не были доставлены до прошлой недели, поэтому условие должно покрыть их!", остановитесь и подумайте об этом на секунду.

на NULL на самом деле не означает, что они не были доставлены. The NULL означает, что мы не знаю, когда они были доставлен. Вполне возможно, что клерк заберет подтверждение завтра и заполнит DeliveryDate как две недели назад, аннулируя данные, которые мы только что получили. Там должно быть не быть нулевыми экземплярами, возвращающимися из этого запроса, и все же есть. Если вы написали тот же запрос в SQL, эти результаты будут исключены.

и почему если вы заботитесь о Nullable<bool> когда C#, по-видимому, нет? Таким образом, вы можете избежать попадания в эту ловушку в своем собственном код:

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));

это немного неудобно, но правильно. Мы написали запрос, который более или менее правильно передает свое намерение, и (bool?)null не равно true или false, поэтому мы получаем правильные результаты в обоих случаях.

Если вам когда - либо нужно оценить условие, в котором ответ может быть "я не знаю" - используйте bool? (он же Nullable<bool>) в результате.

таким образом, абонент может решите, как обрабатывать ответ "я не знаю", а не просто выбирать значение по умолчанию. Все остальное означает, что ваш класс врет.


a null значение означает "нет значения" или "значение неизвестно". В этом случае это не правда и не ложь, но undefined.

см.:http://en.wikipedia.org/wiki/Many-valued_logic


Это хорошо, когда что-то еще не ответил - Думаю, анкеты. У вас есть список вопросов y/n, и только на некоторые из них были даны ответы. Вы не хотите публиковать true или false в таблице базы данных, потому что пользователь еще не ответил на вопрос.


Это может быть неизвестно в дополнение к true или false..в земле базы данных NULL обычно означает неизвестно или нет значения


ленивый программирования!

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

значение null означает

  • Я не знаю.
  • недостаточно данных в настоящее время
  • состояние кошки до открытия коробки
  • Я еще не решил
  • прибыль

значение null означает му


Я использовал его в значении фильтра. В основном у меня есть поле bool в базе данных, но я хотел три состояния: только возвращать строки, где значение true, только возвращать строки, где значение false, не фильтровать и возвращать все строки.

без nullable bool мне пришлось бы использовать либо перечисление, либо второй bool, чтобы определить "фильтр по этому полю да/нет", который добавит раздувание.


быть nullable может означать, что bool не был установлен или инициализирован, если это то, что вашей программе может понадобиться знать


Ну, я мог видеть, что он используется как" еще не определен", я использую bools все время, и иногда просто двух значений недостаточно!! например:

bool? bl;

bl = true; //Yes

bl = false; //No

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

на мой взгляд, это только третье значение для bool.


Если вы собираетесь использовать Nullable bool, я бы рассмотрел использование перечисления или другой структуры данных. Это может помочь вам избежать ошибок, когда значение NULL неизвестно.

недавно я неправильно обращался с Nullable bool. Я не буду вдаваться в детали ошибки, но давайте просто скажем, что это было достаточно плохо, чтобы потребовать полного отката. Я начал задаваться вопросом, насколько практично использовать его в большинстве приложений. (Отчасти в попытке удержать мою сломленную гордость в результате глупости ошибка )

затем я наткнулся на этот пост и принятый ответ Ли.

кажется, это имеет смысл, но чем больше времени я провожу с ним, ответ становится ложным на практике вместо NULL. NULL слишком нечеткий.

прежде чем ответить на этот вопрос, нужно было бы назначить очень конкретное значение NULL. Означает ли NULL, что в вычислении была ошибка? Что делать, если есть ошибка в расчете, прежде чем будет определено, что есть только два дети? (Я также утверждаю, что если действительно есть только двое детей, это можно было бы решить до того, как вопрос был задан программе.)

потому что мы не знаем, что означает NULL, и потому что это определенно не так (потому что, как это может быть? лучший ответ-Ложь.

кроме того, если этот вопрос действительно возвращает NULL, мы ввели новое определение в домен. Какова сфера применения этого определения?

таким образом, казалось бы, что TRUE или FALSE государства представляют собой определенность в отношении результата. NULL можно представить по крайней мере в трех разных состояниях. Например, заявление " Томас вчера вечером пошел в бар."

правда-да, Томас пошел в бар. (самый вероятный ответ, если бы вы знали Томаса) Нет, Томас не пошел в бар. Нуль-а? Knowable-что-то пошло не так в первом расчете. Например. вы задали вопрос Томасу, но чихнули, когда он ответил, и на мгновение оглохли. Просто спросите его снова получите ответ.

непознаваемый-бар сгорел, и Томас покинул город. Нет никакого реального способа получить ответ. (Пожалуйста, не тыкать дырки в этом, но я знаю, что вы будете)

неприменимо-см. пример выше, касающийся трех детей, но вместо этого бары и Томасы.

Что означает NULL здесь? Определение того, что означает NULL, должно выполняться в каждом конкретном случае. Вот почему я считаю, что часто лучше использовать перечисление или другая структура, поскольку она более изящно раскрывает намерение за недвоичным возвращаемым значением.


вы хотели бы использовать это, чтобы