7

如果条件相同但条件不同,switch case 语句可以很好地替换嵌套的 if 语句。但是,如果那些嵌套的 if 语句都具有不同且独特的条件,那么有什么好的方法呢?我是否有任何替代选项来替换嵌套在彼此内部的十几个 if else 语句?

示例代码:

  • 注意:我知道这是非常难以理解的——这就是重点。
  • 注意:所有条件都是唯一的。

...

if (condition) {
    // do A
} else {                       
    if (condition) {
        // do B
    if (condition) {
        if (condition) {
            if (condition) {
                // do C
                if (condition) {
                    // do D
                    if (condition) {
                        // do E
                    } else {                                                   
                        if (condition) {
                            // do F
                        }
                    }
                }
            }

            if (condition) {
                // do G
                if (condition) {
                    // do H
                    if (condition) {
                        // do I
                    } else {
                        // do J
                    }
                }
            }
        }
    }
}

​</p>

4

6 回答 6

3

在这种情况下,最好的方法是将事物分割成适当命名的单独方法。

于 2012-11-08T22:22:45.043 回答
1

在我看来,存在两种消除嵌套条件的主要方法。当我们在每个嵌套条件中只有一个条件时,第一个用于更特殊的情况,如下所示:

function A(){
    if (condition1){
        if (condition2){
            if (condition3){
                // do something
            }
        }
    }
}

我们可以从相反的条件返回:

function A(){
    if (condition1 == false) return;
    if (condition2 == false) return;
    if (condition3 == false) return;  
    // do something 
}

第二个是使用条件分解,可以被视为比第一个更通用。在我们有这样的条件结构的情况下,例如:

if (condition1)  
{
    // do this 1
}
else 
{                                                   
    if (condition2) 
    {
        // do this 2
    }                                                    
}

我们可以为每个特定条件实现一个变量,如下所示:

bool Cond1 = condition1;
bool Cond2 = !condition1 && condition2;

if (Cond1) { //do this 1 }
if (Cond2) { //do this 2 }
于 2012-11-08T22:39:18.783 回答
1

@Tar 提出了一种看待它的方式。另一个可能是。

反转它。

if (myObject.HasThing1)
{
   if(myObject.HasThing2)
   {
      DoThing1();
   }
   else
   {
      DoThing2();
   }
}
else
{
   DoThing3();
}

可能

DoThing1(myObject.HasThing1);
DoThing2(myObject.HasThing2);
DoThing3(myObject.HasThing3);

因此,每个 Do 方法都会进行最少数量的测试,如果有任何失败,它什么也不做。

如果你想以几种方式打破顺序,你可以让它更聪明一点。

不知道它是否对您有用,但是委托测试条件通常足以成为一种看待事物的新方式,一些简化因素可能就像魔术一样出现。

于 2012-11-08T22:45:03.437 回答
1

当我看到代码时,我不得不检查这是 Stackoverflow 而不是 DailyWTF!

解决方案是改变架构并使用接口和多态来绕过所有条件。然而,这可能是一项艰巨的工作,超出了可接受的答案范围,所以我将推荐另一种方式,您可以使用具有独特条件的 Switch 语句:

[Flags]
public enum FilterFlagEnum
{
    None = 0,
    Condition1 = 1,
    Condition2 = 2,
    Condition3 = 4,
    Condition4 = 8, 
    Condition5 = 16,
    Condition6 = 32,
    Condition7 = 64 
}; 


public void foo(FilterFlagEnum filterFlags = 0)
{
        if ((filterFlags & FilterFlagEnum.Condition1) == FilterFlagEnum.Condition1)
        {
            //do this
        }
        if ((filterFlags & FilterFlagEnum.Condition2) == FilterFlagEnum.Condition2)
        {
            //do this
        }
}


foo(FilterFlagEnum.Condition1 | FilterFlagEnum.Condition2);
于 2012-11-09T04:08:15.873 回答
0

如果这确实是业务逻辑,那么语法就可以了。但我从未见过如此复杂的业务逻辑。画一个流程图,看看是否不能简化。

if (condition)  
{
    // do this
}
else 
{                                                   
    if (condition) 
    {
        // do this
    }                                                    
}

可以替换为

if (condition)  
{
    // do this
}
else if (condition) 
{
    // do this                                                    
}

但再次退后一步,审查设计。如果清理,需要的不仅仅是其他。

于 2012-11-08T22:42:20.403 回答
0

我感觉到你的痛苦。

我的情况需要编写许多(>2000 个)功能测试,这些测试是客户为大型、昂贵的设备指定的。虽然这些测试中的大多数(> 95%)都很简单并且有一个直接的通过/失败检查,但数十个在与您的深度相似或更差的深度落入“多重嵌套,如果这样做,否则会做不同的事情”。

我想出的解决方案是在我的测试应用程序中托管 Windows Workflow。

所有复杂的测试都变成了我运行的工作流程,并将结果报告回我的测试应用程序。

客户很高兴,因为他们有能力:

  1. 验证测试逻辑(对于非程序员来说很难查看深度嵌套的 if/else C# - 很容易查看图形流程图)
  2. 以图形方式编辑测试
  3. 添加新测试

托管 Windows 工作流(在 .NET 4/4.5 中)非常容易 - 尽管您可能需要一段时间才能了解工作流和代码之间的“通信” - 主要是因为有多种方法可以做到这一点。

祝你好运

于 2013-08-05T15:34:39.487 回答