缩短嵌套的IF

时间:2016-05-16 18:48:25

标签: c# if-statement

我有以下代码可以完美运行。然而,只是看着它让我相信必须有一个更短,更优雅的方式。 Switch()显然不是答案,所以我坚持使用嵌套if。

if (mode  == 1)
{
   if (distance <= 4000)
   {
       modeValue = "1F";
   }

   else if (distance > 4000 && distance <= 8000)
   {
       modeValue = "2F";
   }

   else if (distance > 8000 && distance <= 12000)
   {
       modeValue = "3F";
   }

   else if (distance > 12000)
   {
       modeValue = "F 0-5";
   }
 }

 else if (mode == 2)
 {
    if (distance <= 500)
    {
        modeValue = "";
    }

    else if (distance > 500 && distance <= 4000)
    {
        modeValue = "2F";
    }

    else if (distance > 4000 && distance <= 8000)
    {
        modeValue = "3F";
    }

    else if (distance > 8000 && distance <= 12000)
    {
        modeValue = "4F";
    }

    else if (distance > 12000)
    {
        modeValue = "F 0-5";
    }
 }

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

一些事情:

首先,您有冗余检查

else if (distance > 500 && distance <= 4000)

可能只是else if (distance <= 4000),因为“其他”部分..你已经在检查距离是否>如果你在其他地方,那就是500。

其次,它实际上取决于周围环境,但这可能是使用多个类的好地方。我将在这里假设这是一个名为CalculateModeValue的方法,并且该方法位于名为Calculator的类中。我还假设“Mode == 1”表示“LongDistance”,而“Mode == 2”表示“ShortDistance”。

在这种情况下,我会有一个名为Calculator的抽象类。然后,我将使用2个单独的类(“LongDistanceCalculator”和“ShortDistanceCalculator”)对其进行子类化。 CalculateModeValue将是Calculator中的抽象方法,并在每个子类中单独实现。这样,您就不需要检查“If Mode == 1”;每个类的实现都将处理该模式的正确逻辑。

但同样,这是对未知数的假设;它实际上取决于这些if语句的上下文。

答案 1 :(得分:1)

使用嵌套ifs的方式没有任何问题。 但如果你真的不想看他们;也许只是在一个接受模式变量的方法中输入逻辑,然后继续将逻辑应用于模式的值?

创建这样的子过程也可以在应用程序中重复使用,以应用相同的计算。

答案 2 :(得分:1)

首先,您应该使用开关替换处理mode的if语句:

switch (mode) {
case 1:
    //...
    break;
case 2:
    //...
    break;
default: break;
}

然后你可以将内部if-else链替换为一个方法(这些被称为&#34;程序&#34;在C#中?):

string Foo(int mode, int distance) {
    switch (mode) 
    { // http://stackoverflow.com/users/469563/gendoikari Thanks for pointing out redundant comparisons
    case 1:
        if (distance <= 4000)
        { return "1F"; }
        else if (distance <= 8000)
        { return "2F"; }
        else if (distance <= 12000)
        { return "3F"; }
        else
        { return "F 0-5"; }
    case 2:
        if (distance <= 500)
        { return ""; }
        else if (distance <= 4000)
        { return "2F"; }
        else if (distance <= 8000)
        { return "3F"; }
        else if (distance <= 12000)
        { return "4F"; }
        else 
        { return "F 0-5"; }
    default: break;
    }
哦,看,无意中发生了一件令人敬畏的事!现在,只要您想要更改Foo,就可以致电modeValue

modeValue = Foo(mode, distance);

答案 3 :(得分:0)

嗯,首先,我只是在没有括号的情况下制作if body one-liners,以便将它缩短到真正的好处。你的原始代码有一些小的调整看起来和恕我直言一样好:

string Func1( int mode, double distance )
{
    if( mode == 1 )
    {
        if( distance <= 4000 )
            return "1F";
        else if( distance <= 8000 )
            return "2F";
        else if( distance <= 12000 )
            return "3F";
        else
            return "F 0-5";
    }
    else
    {
        if( distance <= 500 )
            return "";
        else if( distance <= 4000 )
            return "2F";
        else if( distance <= 8000 )
            return "3F";
        else if( distance <= 12000 )
            return "4F";
        else
            return "F 0-5";
    }
}

如果你不喜欢这样,有很多方法可以做到这一点。怎么样:

class Mode
{
    public double Distance;
    public string Name;
    public Mode( double d, string n ) { this.Distance = d; this.Name = n; }
}

string Func( int mode, double distance )
{
    Mode[] modes;
    if( mode == 1 )
        modes = new Mode[] { new Mode( 4000, "1F" ),
                             new Mode( 8000, "2F" ),
                             new Mode( 12000, "3F" ),
                             new Mode( double.MaxValue, "F 0-5" ) };
    else
        modes = new Mode[] { new Mode( 500, "" ),
                             new Mode( 4000, "2F" ),
                             new Mode( 8000, "3F" ),
                             new Mode( 12000, "4F" ),
                             new Mode( double.MaxValue, "F 0-5" ) };

    for( int pos = 0; ; pos++ )
        if( distance <= modes[pos].Distance )
            return modes[pos].Name;
}

显然你可以重用那些数组。或者你可以让每个模式携带一个Predicate<T>或类似的东西来指定选择该模式的条件。我想Mode类可能只是KeyValuePair<TKey,TValue>来缩短它。