Подтвердить что ты не робот

С# || оператор не работает с нулевыми булевыми

У меня есть следующий фрагмент кода в моей LINQ:

    where (tf.Shipped || tf.Ordered || tf.Processed)

Обратите внимание, что отправленные, упорядоченные и обработанные все допустимые значения Boolean fields

Получаю следующее сообщение:

Оператор || не может применяться к операндам типа "bool?" и 'bool?'

Не уверен, как разрешить это как "да", они должны быть с нулевым значением booleans, и мне нужно использовать OR (||).

4b9b3361

Ответ 1

Сделайте шаг назад и подумайте о проблеме. Вам нужна коллекция виджетов, где был заказан виджет, или был отправлен виджет, или виджет был обработан.

Существует четыре возможных состояния для вашего знания "упорядоченного":

  • этот виджет был заказан , и я знаю, что (true)
  • этот виджет не был заказан , и я знаю, что (false)
  • этот виджет был заказан , но я не знаю, что (null)
  • этот виджет не был заказан , но я не знаю, что (null)

Существует четыре состояния, но возможны только три значения. Поэтому, если "упорядоченное" находится в нулевом состоянии, вы не знаете, должно ли оно быть включено в результаты запроса или нет.

Компилятор тоже этого не знает.

Просто не хватает информации, доступной компилятору, чтобы дать вам запрос с семантикой, которую вы хотите. Компилятор не собирается делать предположения и, возможно, дает вам плохие результаты; компилятор скажет вам, что здесь недостаточно информации, и вам нужно сделать больше работы, чтобы сделать запрос однозначным.

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

where (tf.Shipped ?? false) || (tf.Ordered ?? false) || (tf.Processed ?? false)

Это означает, что "если я не знаю, было ли отправлено и т.д., предположим, что это не так".

Вместо этого вы можете запросить "все виджеты, которые определенно были или могут быть отправлены, заказаны или обработаны:

where (tf.Shipped ?? true) || (tf.Ordered ?? true) || (tf.Processed ?? true)

Компилятор не собирается догадываться, с какой стороны вы хотите ошибиться, когда недостаточно информации для получения точных результатов; компилятор может ошибиться, и мы не принимаем решения от вашего имени. Вы должны будете принять это решение.

Ответ 2

Try

 where (tf.Shipped == true || tf.Ordered  == true || tf.Processed == true )

Ответ 3

Вам нужно убедиться, что выражение никогда не null. Вы можете сделать это с помощью оператора null-coalesce, ??:

where ((tf.Shipped ?? false) || (tf.Ordered ?? false) || (tf.Processed ?? false))

Ответ 4

where ((tf.Shipped.HasValue && tf.Shipped.Value)
       || (tf.Ordered.HasValue && tf.Ordered.Value)
       || (tf.Processed.HasValue && tf.Processed.Value))

Ответ 5

Вы также можете использовать GetValueOrDefault в вашем конкретном случае.

where (tf.Shipped.GetValueOrDefault()
    || tf.Ordered.GetValueOrDefault()
    || tf.Processed.GetValueOrDefault() )

Ответ 6

where ((tf.Shipped.HasValue && tf.Shipped.Value) 
   || (tf.Ordered.HasValue && tf.Ordered.Value) 
   || (tf.Processed.HasValue && tf.Processed.Value))