14

With this code:

private bool AtLeastOnePlatypusChecked()
{
    return ((ckbx1.IsChecked) ||
            (ckbx2.IsChecked) ||
            (ckbx3.IsChecked) ||
            (ckbx4.IsChecked));
}

...I'm stopped dead in my tracks with

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

So how do I accomplish this?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

6 Answers6

31

You can chain together |s, using the null-coalescing operator at the end:

return (ckbx1.IsChecked | cxbx2.IsChecked | cxbx3.IsChecked | cxbx4.IsChecked) ?? false;

The lifted | operator returns true if either operand is true, false if both operands are false, and null if either operand is null and the other isn't true.

It's not short-circuiting, but I don't think that'll be a problem for you in this case.

Alternatively - and more extensibly - put the checkboxes into a collection of some kind. Then you can just use:

return checkboxes.Any(cb => cb.IsChecked ?? false);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Finally I know what "lifted" means. I encountered this term when working with expression trees. – Olivier Jacot-Descombes Dec 18 '12 at 22:05
  • I was curious about that term too, but it looks like [Jon has already answered that question](http://stackoverflow.com/questions/3370110/what-are-lifted-operators) – Mike Christensen Dec 18 '12 at 22:21
  • I believe the | operand doesn't use short-circuit evaluation, so there is potentially a slight performance impact, probably negligible for this example. – Joe Dec 18 '12 at 22:31
  • @OlivierJacot-Descombes: See http://blogs.msdn.com/b/ericlippert/archive/2007/06/27/what-exactly-does-lifted-mean.aspx for a detailed discussion. Also, I will be returning to this subject later this month in my new blog, which is at http://ericlippert.com, if this subject interests you. – Eric Lippert Dec 18 '12 at 23:05
  • @EricLippert: Thanks for the link. What does the term `null` mean in the mathematical context? – Olivier Jacot-Descombes Dec 18 '12 at 23:09
  • @OlivierJacot-Descombes: Whatever you want it to mean :-) -- I'm assuming that there is some value called null that can go in a set. What precisely that value is depends on how you choose to construct the rest of the objects that can go in the set. There are a lot of sets to choose from, so surely we can find one that isn't being used for something else. – Eric Lippert Dec 18 '12 at 23:13
  • It is worth noting that the lifted `|` and `&` operators are an exception to the usual convention (usual in C# that is) for lifted binary operators. The "normal" case is to return `null` (of the `Nullable<>` type in question) as soon as just _one_ of the two operands does not `HasValue`. The binary comparison operators `==`, `!=`, `>`, `<`, `>=`, `<=` in their lifted forms are another kind of exception since their lifted return type is `bool` in C#, not `bool?`. – Jeppe Stig Nielsen Dec 18 '12 at 23:20
  • @EricLippert (1) The blog post you linked doesn't mention the exception I just explained, so someone reading only that blog post might think Skeet's answer above is wrong (it is not!). (2) I hope you guys don't forget to fix [this misleading compiler warning message](http://stackoverflow.com/questions/13046115/) with lifted relational operators on non-simple types. – Jeppe Stig Nielsen Dec 18 '12 at 23:34
  • @JeppeStigNielsen: I was responding to Olivier's comment about not knowning what "lifted" meant; since the C# language uses this term in an inconsistent way I thought it worthwhile to point that out. Jon's answer is, of course, correct. – Eric Lippert Dec 19 '12 at 00:21
  • 1
    @JeppeStigNielsen: And I fixed that bug in Roslyn before I left. I am no longer one of "those guys". :-) – Eric Lippert Dec 19 '12 at 00:21
11

Try:

return ((ckbx1.IsChecked ?? false) ||
        (ckbx2.IsChecked ?? false) ||
        ...
Joe
  • 122,218
  • 32
  • 205
  • 338
6

I'm assuming that if null, then it'll be false, you can use the ?? operator.

 private bool AtLeastOnePlatypusChecked()
 {
      return ((ckbx1.IsChecked ?? false) ||
      (ckbx2.IsChecked ?? false) ||
      (ckbx3.IsChecked ?? false) ||
      (ckbx4.IsChecked ?? false));
 }
Bob.
  • 3,894
  • 4
  • 44
  • 76
5

You can use GetValueOrDefault() to get either the value, or false.

private bool AtLeastOnePlatypusChecked()
{
    return ((ckbx1.IsChecked.GetValueOrDefault()) ||
            (ckbx2.IsChecked.GetValueOrDefault()) ||
            (ckbx3.IsChecked.GetValueOrDefault()) ||
            (ckbx4.IsChecked.GetValueOrDefault()));
}
Mike Christensen
  • 88,082
  • 50
  • 208
  • 326
4

You can use the following:

(ckbx1.IsChecked.HasValue && ckbx1.IsChecked.Value)
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 2
    Should the `||` be the `&&` operator? If `cbx1.IsChecked.HasValue` is `false` then there will be a `Null Reference` when getting `ckbx1.IsChecked.Value`. – Shane Charles Dec 18 '12 at 22:09
2

Use ?? operator inside your method;

private bool AtLeastOnePlatypusChecked()
{
return ((ckbx1.IsChecked ?? false) ||
        (ckbx2.IsChecked ?? false) ||
        (ckbx3.IsChecked ?? false) ||
        (ckbx4.IsChecked ?? false)
}
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364