Question

Consider this function, which you can think of as a truth table:

public Foo doSomething(bool a, bool b) {

       if ( a &&  b) return doAB();
  else if ( a && !b) return doA();
  else if (!a &&  b) return doB();
  else if (!a && !b) return doNotANotB();

  else throw new Exception("Well done, you defeated boolean logic!");
}

The compiler insists on that last else clause. But from a truth table's perspective, that is an impossible state.

Yes, it works, and yes, I can live with it. But I'm wondering if there is some mechanism in c# to avoid this sort of code, or if I've missed something obvious?

UPDATE:
For bonus points, and purely out of curiosity, are there any languages that deal with this sort of thing differently? Maybe it's not a language matter, but rather one of a smart compiler (but the edge cases would be unimaginably complicated I suppose).

Was it helpful?

Solution

Considering the truth table, the last condition is entirely superfluos. It can be dropped without altering the logic of your program, like this:

public MyType doSomething(bool a, bool b) {

      if ( a &&  b) return doAB();
else  if ( a && !b) return doA();
else  if (!a &&  b) return doB();
else/*if (!a && !b)*/ return doNotANotB();
}

Now you have a final catch-all if, and your compiler is happy. You don't have to remove the condition altogether - I often find it a good idea to keep it around in a comment for readability.

OTHER TIPS

if(a) return b ? doAB() : doA();
else return b ? doB() : doNotAnotB();

Or shorter:

return a ? (b ? doAB() : doA())
         : (b ? doB() : doNotAnotB());

Try f#. If it can detect exhaustive condition matching with its match directive then it doesn't require an else.

http://ganesansenthilvel.blogspot.co.at/2011/12/f-pattern-matching.html?m=1#!

> let testAND x y =
match x, y with
| true, true -> true
| true, false -> false
| false, true -> false
| false, false -> true

> testAND true false;;
val it: bool = true

and for an incomplete specification

> let testAND x y =
match x, y with
| true, true -> true
// Commented | true, false -> false 
| false, true -> false
| false, false -> true
> testAND true false;;

the compiler will say

Microsoft.Fsharp.Core.MatchFailureExcption: The match cases were incomplete at:....
Stopped due to error
 public MyType doSomething(bool a, bool b)
        {
            switch(a)
            {
                case true:
                    if (b) return doAB();
                    return doA();
                default:
                    if (b) return doB();
                    return doNotANotB();

            }

        }

Update:

Note that your original statement is actually:

  public MyType doSomething(bool a, bool b)
        {
            if (a && b) return doAB();
            if (a) return doA();
            if (b) return doB();
            return doNotANotB();
        }

For fun and succintnes (if not readability :p):

static MyType doSomething(bool a, bool b)
        {
            return a && b ? doAB() : a ? doA() : b ? doB() : doNotANotB();
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top