Операция AND не может применяться между допускаемыми значениями bools - PullRequest
8 голосов
/ 03 декабря 2010

Я применяю операцию И (&&) между двумя обнуляемыми логическими значениями (bool?), но выдает ошибку, что

Оператор && нельзя применять к операндам типа bool? и bool?

Как мне применить и работать в моем утверждении, которое содержит два допускаемых по значению bool?

Также, если у меня есть результат диалога, такой как

dialog.ShowDialog () == DialogResult.OK

Как я могу преобразовать его в nullable bool, так как мне нужно поместить оператор '&&' с этим условием if, другой операнд которого возвращает nullable bool? Вот код:

if (dialog.ShowDialog () == DialogResult.OK && CheckProjectPath(dialog.FileName, true))

второй операнд в этом условии, если условие является недействительным bool.

Ответы [ 5 ]

18 голосов
/ 03 декабря 2010

Как мне применить и выполнить операцию в моем утверждении, содержащем два допускающих обнуление bools?

Ну, что вы хотите, чтобы произошло?Причина, по которой это неверно, заключается в том, что плохие вещи случаются, если первый операнд имеет значение null.

Что означает x && y для логических значений, допускающих нулевое значение x и y?Ну, что в первую очередь означает обнуляемый логический тип?Обнуляемое логическое значение означает одно из трех:

  • Условие определенно истинно
  • Условие определенно ложно
  • Условие истинно или ложно, но мы этого не делаемзнаете, какой

Так что же означает x && y?Это означает «вычислять y, только если условие x истинно», но если x обнуляемо, то мы можем не знать, является ли условие, представленное x, истинным или нет .

Например, предположим, чтоу нас есть:

gotMoneyInZurich = SalesForNovemberWereMoreThanAMillionBucks() &&
    TryToDepositAMillionBucksInASwissBankAccount();

Если SalesForNovemberWereMoreThanAMillionBucks имеет значение false, не пытайтесь внести деньги, и мы знаем, что у нас нет денег в банке.Если это правда, то попробуйте внести деньги;если это не удастся, то у нас нет денег в Цюрихе;если это удастся, мы сделаем это.

Теперь предположим, что не все продавцы сообщили свои показатели продаж за ноябрь .Мы знаем, были ли продажи за ноябрь более миллиона долларов?Нет, ноябрь в прошлом;либо продажи были, либо они были не более миллиона долларов, но сейчас мы не знаем .Правильный ответ не «ложь», правильный ответ не «истина»: правильный ответ «мы не знаем»: нуль.

Так что же делать, если первый возвращает нольоперанд?Мы не знаем, были ли продажи более миллиона долларов, поэтому правильно ли пытаться внести деньги или не пытаться внести деньги?Должны ли вы предпринимать действия на основании недостающей информации или нет?

Компилятор не может решить этот вопрос за вас. Если вы не хотите вносить деньги, если результатнеизвестно, тогда вы должны сказать, что: (SalesForNovemberWereMoreThanAMillionBucks() ?? false) означает «если результат был нулевым, трактуйте его как ложный».

Аналогично, если вы говорите:

if(x && y)
    Frob();

и x - это правда, а y - это ноль, тогда что вы должны делать?Вы говорите: «Frob, только если x и y оба истинны. X истинно, и мы не знаем, верно ли y или нет».Так ты должен Фроб или нет? Вы не знаете . Компилятор тоже не знает. Если то, что вы хотите сказать, это «Frob, если x истинно, а y либо true, либо null», то скажите:

if(x && (y ?? true))
    Frob();

Или,«frob, если x истинно, а y истинно, но не если y равно нулю», тогда скажите, что:

if(x && (y ?? false))
    Frob();

Теперь, если вы не используете оператор && для оценки короткого замыкания, тогда не используйте оператор && в первую очередь .Используйте оператор &;он всегда оценивает обе стороны, поэтому здесь нет никакой двусмысленности.Совершенно законно говорить «x & y», если x и y являются допускаемыми значениями bools;результат будет нулевым, если x или y равны нулю, true, если x и y оба равны true, и false в противном случае.Вы все еще не можете использовать эту вещь в «если», конечно;это требует bool, а не nullable bool.Но вы можете сказать:

bool? result = x & y;

, где x и y - обнуляемые числа.

7 голосов
/ 03 декабря 2010

Вы можете использовать что-то вроде

bool? b1 = ...;
bool? b2 = ...;    
bool b = (b1 ?? true) && (b2 ?? false);

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

Как я могу преобразовать его в nullable bool, так как мне нужно поместить оператор '&&' с этим оператором if, чей другой операнд возвращает nullable bool?

Вы должны пойти другим путем: вы не можете выполнять операции с операндом, допускающим обнуление, поэтому вы должны попытаться преобразовать из bool? в bool.Оператор ??здесь очень полезно:

 if (dialog.ShowDialog () == DialogResult.OK 
     && CheckProjectPath(dialog.FileName, true) ?? false)

Относительно "нуль-сливающегося оператора" ??:

int? a, b, c;
...
int d = a ?? b ?? c ?? -1;

если a, b и c все null, то d становится -1.Если кто-либо из них не равен нулю, используется первое значение.

1 голос
/ 03 декабря 2010
if (dialog.ShowDialog () == DialogResult.OK &&
    CheckProjectPath(dialog.FileName, true).GetValueOrDefault())

Операция && не определена для null с. Следовательно, вы должны убедиться, что оба логических значения не имеют значения NULL, и самый простой способ сделать это - вызвать метод GetValueOrDefault() для NULL.

1 голос
/ 03 декабря 2010

Я просто предполагаю, что вы можете попробовать

if ((dialog.ShowDialog() == DialogResult.OK )&& 
            (CheckProjectPath(dialog.FileName, true) == true ) )
0 голосов
/ 03 декабря 2010
if (dialog.ShowDialog () == DialogResult.OK) 
{
    var checkProjectPath =  CheckProjectPath(dialog.FileName, true);
    if (checkProjectPath.HasValue && checkProjectPath)) {/*Your Action*/}
}

Если целью функции CheckProjectPath является проверка пути, я не вижу никакой причины, по которой результат должен быть bool?

...