通过范围值获取测试分数

时间:2013-09-10 08:14:20

标签: c# if-statement dictionary decimal

我有一个要求,我在下面取一个int(示例中的分数)并通过将其与各种范围条件进行比较来返回小数值。如果得分在1到10之间,则测试自动失败并且不返回小数(在这种情况下,我返回字符串“FAILED”。高于10然后根据范围得分匹配返回相应的小数值。这样做感觉不对,并且想知道是否有更好的方法。我考虑使用一个字典,每个范围,例如1到10之间存储在一个键中,然后查询这个以返回值。但是,我不确定如何这样做。有人能提出更好的方法吗?

谢谢

public decimal GetTestScore(int score, out string status)
    {
        decimal score = 0m;
        string status = string.Empty;

        if(score >= 1 && score <= 10)
             status = FAILED;
        else if(score >= 10 && score <= 20)
            score = 1.0;
        else if(score >= 20 && score <= 30)
            score = 2.0;
        else if(score >= 30 && score <= 40)
            score = 3.0;
        return score;
    }

3 个答案:

答案 0 :(得分:0)

首先返回一个可以为空的十进制数,如果验证失败,只需返回null。

public decimal? GetTestScore(int score)

另一个问题是:为什么感觉不对?对于简单的应用,这就足够了。

不要过度设置问题。

在您的情况下,字典不是空间有效的,因为您需要许多冗余值来将范围映射到一个单独的分数值。

您的解决方案实际上是错误的,因为您要与得分&lt; = 20进行比较,然后对于下一个得分值&gt; = 20这是多余的(即使行为正确)

编辑:如果约束是可投影的,您当然可以简化检查

    public decimal? GetTestScore(int score)
    {

        if (score >= 1 && score <= 10)
        {
            return null;
        }

        if (score < 1 || score > 40)
        {
            return 0;
        }

        return (score-1) / 10;
    }

再次编辑:添加边界条件

答案 1 :(得分:0)

我认为这可行:

public decimal GetTestScore(int score, out string status)
{
    status = string.Empty;

    if (score < 10)
    {
        status = "FAILED";

        return 0m;
    }

    return Math.Ceiling(score / 10m);
}

答案 2 :(得分:0)

如果您预测您的解决方案可能需要扩展以容纳更多分数定义,或者具有用户可配置的分数定义,您可以使用类似以下示例的内容:

public class ScoreResult
{
    public int Low { get; set; }
    public int High { get; set; }
    public string Status { get; set; }
    public double ReplacementScore { get; set; }

    public ScoreResult(int low, int high, string status, 
          double replacementScore)
    {
        Low = low;
        High = high;
        Status = status;
        ReplacementScore = replacementScore;
    }
}

public class ScoreCalculator
{
    private List<ScoreResult> _scores = new List<ScoreResult>();

    public ScoreCalculator()
    {
        /*These are easy to change and could be
          loaded from a database/service*/
        _scores.Add(new ScoreResult(1, 10, "FAILED", 0));
        _scores.Add(new ScoreResult(10, 20, string.Empty, 1));
        _scores.Add(new ScoreResult(20, 30, string.Empty, 2));
        _scores.Add(new ScoreResult(30, 40, string.Empty, 3));
    }

    public ScoreResult GetScoreResult(int score)
    {
        //Will return null if no match found
            return _scores.FirstOrDefault
                    (s => score >= s.Low && score <= s.High);
    }
}

使用示例:

    var result = GetScoreResult(9);
    Console.WriteLine(result.Status); //FAILED
    Console.WriteLine(result.ReplacementScore); //0.0

每个分数都可以用ScoreResult的实例来表示,这样可以很容易地找到使用Linq的匹配,并且很容易添加/删除/修改您的分数。您甚至可以将ScoreResult数据存储在数据库中,以便可以轻松配置。