Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
222 views
in Technique[技术] by (71.8m points)

C# || operator not working with nullable booleans

I have the following piece of code in my LINQ:

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

Note that Shipped, Ordered and Processed are all nullable Boolean fields

I am getting the following message:

Operator || cannot be applied to operands of type 'bool?' and 'bool?'

Not sure how to resolve this as yes, they need to be nullable booleans and I need to use the OR (||).

question from:https://stackoverflow.com/questions/9037171/c-sharp-operator-not-working-with-nullable-booleans

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Take a step back and think about the problem. You want a collection of widgets where the widget was ordered, or the widget was shipped, or the widget was processed.

There are four possible states for your knowledge of "ordered":

  • this widget was ordered and I know that (true)
  • this widget was not ordered and I know that (false)
  • this widget was ordered but I don't know that (null)
  • this widget was not ordered but I don't know that (null)

There are four states but only three values possible values. Therefore if "ordered" is in the null state you do not know whether it should be included in the query results or not.

The compiler doesn't know that either.

There simply is not enough information available for the compiler to give you a query that has the semantics you want. The compiler is not going to make a guess and possibly give you bad results; the compiler is going to tell you that there's not enough information here and you need to do more work to make the query unambiguous.

What you have to do is say what to do in the case where you don't know the answer. The query "all the widgets that were ordered, shipped or processed" is impossible because some widgets we don't know whether they were ordered, shipped or processed, and so we don't know whether to include them or not. But the query "all the widgets that I know were ordered, or that I know were shipped, or that I know were processed" is a query that the compiler can make sense of:

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

That means "if I don't know whether it was shipped, etc, assume it was not".

You might instead want the query "all the widgets that definitely were, or might have been shipped, ordered or processed:

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

The compiler isn't going to guess which side you want to err on when there is insufficient information to give accurate results; the compiler might guess wrong and we're not in the business of making decisions on your behalf. You're going to have to make that decision.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...