11

考虑这个函数,您可以将其视为真值表:

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!");
}

编译器坚持最后一个else子句。但从真值表的角度来看,这是一个不可能的状态。

是的,它有效,是的,我可以忍受它。但我想知道 C# 中是否有某种机制可以避免这种代码,或者我是否遗漏了一些明显的东西?

更新:
对于奖励积分,纯粹出于好奇,是否有任何语言以不同的方式处理此类事情?也许这不是语言问题,而是智能编译器之一(但我想边缘情况将是难以想象的复杂)。

4

4 回答 4

18

考虑到真值表,最后一个条件完全是多余的。可以在不改变程序逻辑的情况下删除它,如下所示:

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();
}

现在你有一个最终的包罗万象if,你的编译器很高兴。您不必完全删除该条件 - 我经常发现将其保留在评论中以提高可读性是一个好主意。

于 2012-11-11T12:16:07.933 回答
7
if(a) return b ? doAB() : doA();
else return b ? doB() : doNotAnotB();

或更短:

return a ? (b ? doAB() : doA())
         : (b ? doB() : doNotAnotB());
于 2012-11-11T15:32:09.080 回答
6

试试 f#。如果它可以检测到与其 match 指令匹配的详尽条件,那么它不需要 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

对于不完整的规范

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

编译器会说

Microsoft.Fsharp.Core.MatchFailureExcption: The match cases were incomplete at:....
Stopped due to error
于 2012-11-11T13:08:54.833 回答
2
 public MyType doSomething(bool a, bool b)
        {
            switch(a)
            {
                case true:
                    if (b) return doAB();
                    return doA();
                default:
                    if (b) return doB();
                    return doNotANotB();

            }

        }

更新:

请注意,您的原始陈述实际上是:

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

为了有趣和简洁(如果不是可读性:p):

static MyType doSomething(bool a, bool b)
        {
            return a && b ? doAB() : a ? doA() : b ? doB() : doNotANotB();
        }
于 2012-11-11T12:37:17.417 回答