C#Multiple If语句替换

时间:2016-03-11 22:56:44

标签: c#

我正在尝试制定一个计算人员整体成绩的练习计划。测试由三个部分组成,每个部分具有不同的权重。第1部分值5级,第2部分3级,第3部分值2级。

因此,如果一个人得到A B C,他们将获得5A 3B和2C。

现在,为了接收和A / B / C整体需要一定数量的每个等级。例如,为了获得总体A,您需要至少有5A和7个等级必须为B或更高,并且所有等级必须为C或更高。

B,C,D等也都有自己的要求。

最好的编码方式是什么,因为我现在每个年级都使用一个计数器,然后在if / else if语句中查看一个人所得到的每个年级的数量:

 if (aGradeCount >= 5)
    {
                //Add total grade
            }
        }
    }

    //To receive a B
    if(bGradeCount >= 3 && aGradeCount <5 && cGradeCount >=2) 
    {
        if(bGradeCount + cGradeCount +dGradeCount + aGradeCount>= 7)
        {
            if(dGradeCount <= 3)
            {

                //Add new total grade
            }
        }
    }

现在我明白这是一种可怕的做法,但我怎么能更好地编码呢?使用switch语句?如果是这样我该怎么做?

5 个答案:

答案 0 :(得分:9)

  

我怎样才能更好地编码?

编写规范。然后,对于规范中提到的每个概念,编写一个方法。这是规范的一部分;你已经写过:

  

要获得总体A,您需要至少有5个A和7个等级必须为B或更高,所有等级必须为C或更高。

分解

in order to receive an A overall
    at least 5 A's AND 
    at least 7 of the grades must be B or higher AND
    all the grades need to be C or better

好的,现在我们可以开始将其变成一种方法:

static bool QualifiesForA(int aCount, int bCount, int cCount, int dCount)
{
    // In order to receive an A overall we require:    

    // TODO: at least 5 A's AND 
    // TODO: at least 7 of the grades must be B or higher AND
    // TODO: all the grades need to be C or better

    // If these conditions are not met then an A is not earned.
    return false;
}

好的,我们已将规范转化为代码。错误的代码,但代码。我们继续吧。我们有一条规范。写一个方法:

static bool AtLeastFiveA(int aCount) 
{
  return aCount >= 5;
}
嘿,这是一个正确的方法。我们正在取得进展。现在使用它:

static bool QualifiesForA(int aCount, int bCount, int cCount, int dCount)
{
    // In order to receive an A overall we require:    
    // at least 5 A's AND 
    // TODO: at least 7 of the grades must be B or higher AND
    // TODO: all the grades need to be C or better

    bool atLeast5A = AtLeastFiveA(aCount);

    // If these conditions are not met then an A is not earned.
    return false;
}

现在我们还有另一个问题。至少7个是B或更高。好的,写一个方法:

static bool AtLeastSevenB(int aCount, int bCount)
{
  return aCount + bCount >= 7;
}

另一种正确的方法!使用它!

static bool QualifiesForA(int aCount, int bCount, int cCount, int dCount)
{
    // In order to receive an A overall we require:    
    // at least 5 A's AND 
    // at least 7 of the grades must be B or higher AND
    // TODO: all the grades need to be C or better

    bool atLeast5A = AtLeastFiveA(aCount);
    bool atLeast7B = AtLeastSevenB(aCount, bCount);
    // If these conditions are not met then an A is not earned.
    return false;
}

现在我们需要最后一点:

static bool NoD(int dCount)
{
  return dCount == 0;
}

把它放在一起。

static bool QualifiesForA(int aCount, int bCount, int cCount, int dCount)
{
    // In order to receive an A overall we require:    
    // at least 5 A's AND 
    // at least 7 of the grades must be B or higher AND
    // all the grades need to be C or better

    bool atLeast5A = AtLeastFiveA(aCount);
    bool atLeast7B = AtLeastSevenB(aCount, bCount);
    bool noD = NoD(dCount);
    if (atLeast5A && atLeast7B && noD) 
      return true;

    // If these conditions are not met then an A is not earned.
    return false;
}

现在,问自己的问题是:

  • 这段代码是否正确?让它正确处理。这段代码非常详细,但我现在告诉你,完全符合你提供的规范。

  • 一旦代码正确,我们可以更清楚地说明吗?

是;我们可以说:

static bool QualifiesForA(int aCount, int bCount, int cCount, int dCount)
{
    // In order to receive an A overall we require:    
    // at least 5 A's AND 
    // at least 7 of the grades must be B or higher AND
    // all the grades need to be C or better

    bool atLeast5A = AtLeastFiveA(aCount);
    bool atLeast7B = AtLeastSevenB(aCount, bCount);
    bool noD = NoD(dCount);
    return atLeast5A && atLeast7B && noD;
}

现在也许你会说,你知道,其中一些方法是不必要的抽象,也许我可以用他们的身体代替它们:

static bool QualifiesForA(int aCount, int bCount, int cCount, int dCount)
{
    // In order to receive an A overall we require:    
    // at least 5 A's AND 
    // at least 7 of the grades must be B or higher AND
    // all the grades need to be C or better

    bool atLeast5A = aCount >= 5;
    bool atLeast7B = aCount + bCount >= 7;
    bool noD = dCount == 0;
    return atLeast5A && atLeast7B && noD;
}

重点是:我们从一个非常详细的,清晰正确程序开始,然后我们进行小而简单,清晰正确的转换,使其更简洁。如果您认为自己在简洁性和可读性方面有很好的平衡,请停止。

好的,现在你已经解决了“我们赚了A吗?”的问题。现在你做“我们赚了B吗?”等等。为每个部分编写规范,然后编写明确实现规范的代码

这听起来像是一个重量级的过程,但是当你学习如何编程时,这将带来巨大的回报。您的代码将更好地组织,它将更少的错误,它将更容易阅读和理解和修改。

这种技术的重点是关注每个部分的明显正确性。始终专注于明显的正确性。一个程序是正确的但你不能说它是正确的程序,可能是不正确的!始终专注于正确性首先。使错误的程序更优雅,更快,或更完整的功能意味着您拥有一个优雅,快速,功能丰富的错误场。

总结:

  • 写清楚的规格。
  • 编写代码以清楚地符合规范。
  • 微小的方法是A-OK。您可以随时消除它们。
  • 正确性比其他一切更重要;一旦你知道它是正确的,就要使代码更好。

答案 1 :(得分:1)

我不知道这是不是很糟糕的做法。这有点不必要,因为块中没有别的东西,而是另一个if语句。你可以使用更多&amp;&amp;运算符和括号如果你只想使用一个if语句。

if ((bGradeCount >= 3 && aGradeCount <5 && cGradeCount >=2)  &&
    (bGradeCount + cGradeCount +dGradeCount + aGradeCount>= 7) &&
    (dGradeCount <= 3))
{
    char b = 'B';
    person.TotalGrade = b.ToString();
}

答案 2 :(得分:1)

为了代码清晰,我会这样做:

//Main function
{
///code
     if(MethodWhichDescribesLogic(aGradeCOunt,bGradeCount,cGradeCount,dGradeCount){
          char b = 'B';
          person.TotalGrade = b.ToString();
     }
}

然后在其他地方:

 bool MethodWhichDescribesLogic(type aGradeCount, type  bGradeCount, type cGradeCount, type dGradeCount){
    return 
       (PassingGrade(bGradeCount,aGradeCount,cGradeCount) &&
       GoodGradesType(bGradeCount,cGradeCount,dGradeCount,aGradeCount) &&
       dGradeCount <= 3);
    }


  bool PassingGradesCount(type bGradeCount,type aGradeCount,type cGradeCount)
  {
      return bGradeCount >= 3 && aGradeCount <5 && cGradeCount >=2;
  }


  bool GoodGradesCount(type cGradeCount,type bGradeCount,type aGradeCount,type dGradeCount)
  {
      return bGradeCount + cGradeCount +dGradeCount + aGradeCount>= 7;
  }

答案 3 :(得分:0)

请记住,每个if-else开关都可以被条件表替换。 因此,如果整体成绩计数为10,那可能是

A   B   C   Overall

5   7   10  A

4   7   10  B

然后你创建它的数组并找到你在数组中的位置。

例如(我承认我对你的例子感到困惑,所以我可能在这里弄错了。):

var grades = new[]{
  new { A = 5. B = 7, C = 10, Overall = "A"},
  new { A = 4, B = 7, C = 10, Overall = "B"},
  ...
}

var myGrade = grades.FirstOrDefault(g => myA >= g.A && myB >= g.B && enoughC)

通过适当的格式化,它看起来比大量的if更好。而且你总是在你面前有你的选择表。

答案 4 :(得分:0)

首先,在OverallGrade()中使用布尔代数来查看不需要考虑哪些案例。例如,如果要检查A等级,您已经看到gradeDistribution.A >= 5,则在测试等级'B'时不要测试gradeDistribution.A < 5,因为很明显,如果您正在测试B的情况,您已将gradeDistribution.A < 5测试为真。

接下来,将等级计算放在另一个方法中,并尽早返回该方法。

最后,为了获得整体成绩,您可以将方法编写为:

private static char OverallGrade(int partA, int partB, int partC)
{
    //Now in this method, check one by one which 
    //overall grade the provided values fall in

    //Call another method to get count of individual As, Bs, Cs etc
    var gradeDistribution = GetIndividualCount(partA, partB, partC);

    //Now, first check for A and return immediately if true
    if (gradeDistribution.A >= 5) return 'A';

    //Now, check for B and again return if the values satisfy for B
    if (gradeDistribution.B >=3 
        && gradeDistribution.C <= 2
        && gradeDistribution.D <= 3
        && ...)
        return 'B';

    //Keep adding for each case and return as soon as you find the grade.
}

现在,可以创建我们上面使用过的变量GradeDistribution,它可以保存每个等级的数量:

public class GradeDistribution
{
    public int A; //Count for Grade A
    public int B; //Count for Grade B
    public int C; //Count for Grade C
    public int D; //Count for Grade D
}

上面的代码是为现实世界中不存在的实体引入类的示例。

接下来,GetIndividualCount()可写为:

private static GradeDistribution GetIndividualCount(int partA, int partB, int partC)
{
    var gradeDistribution = new GradeDistribution();
    /*

    Calculate and assign values to gradeDistribution.A, gradeDistribution.B...

    */
    return gradeDistribution;
}