有没有办法快捷这个if if / else if return方法?

时间:2012-05-29 15:56:22

标签: c#

我有这个很长的方法:

public decimal decDiscount(QuoteData quoteData)
    {
        if (TotalChapter7(quoteData) >= 7499)
            return 5300;
        else if (TotalChapter7(quoteData) >= 7449)
            return 5300;
        else if (TotalChapter7(quoteData) >= 7399)
            return 5250;
        else if (TotalChapter7(quoteData) >= 7349)
            return 5200;
        else if (TotalChapter7(quoteData) >= 7299)
            return 5200;
        else if (TotalChapter7(quoteData) >= 7249)
            return 5150;
        else if (TotalChapter7(quoteData) >= 7199)
            return 5100;
        else if (TotalChapter7(quoteData) >= 7149)
            return 5100;
        else if (TotalChapter7(quoteData) >= 7099)
            return 5050;
            //...
        else if (TotalChapter7(quoteData) >= 1199)
            return 1100;
        else if (TotalChapter7(quoteData) >= 1149)
            return 1100;
        else if (TotalChapter7(quoteData) >= 1099)
            return 1050;
        else if (TotalChapter7(quoteData) >= 1049)
            return 1000;
        else
            return 0;
    }

具有重复模式,可以通过以下Excel工作表进行说明:

Excel sheet part 1 ......>>>> Excel sheet part 2

从最高“费用”(7499)开始,每项声明的费用下降50。但是,回报(或“折扣价”)每100个保持相同(费用两个50滴),然后一个回报减少50个(费用减少50个),然后重复。

你可以看到我的方法很长(我在7049和1249之间遗漏了)。我有什么办法可以缩短这个吗?

感谢。

7 个答案:

答案 0 :(得分:3)

你们真的过于复杂了。尝试使用整数运算来解决这个问题的任何方法都是一个坏主意。看看对于一群非常聪明的人(我们都非常聪明,不是吗?)来说,首先要做到这一点是多么困难。它真的很难被发现,它真的很难理解,很难做到正确,而且这是一个难以维护。

您需要一种易于理解且易于维护的方法。看看你的原帖,你有一个规则的英文描述。

  

然而,回报(或“折扣价”)每100个保持相同(费用两个50滴),然后一个回报减少50个(费用减50个),然后重复。

代码实际上写了自己:

public int GetFeeFromQuoteData(QuoteData quoteData) {
    int fee = 5300;
    int difference = 7449 - TotalChapter7(quoteData);
    bool isTwoStep = true;

    while (difference > 0) {
        if (isTwoStep) {
            difference -= 50;
        }
        else {
            difference -= 100;
        }
        fee -= 50;
        isTwoStep = !isTwoStep;
    }
    return fee;
}

答案 1 :(得分:2)

这些价格&折扣 DATA !绝不应将数据编译成代码

我不会将代码构建到代码中,我会构建基础定价结构(它们可能会与价格下降有关,但不太可能改变整体定价结构)。

我有价格&反映此结构的易于更改的地方(例如数据库,xml文件)中的相关折扣。

public class Pricing
{
     private List<Tuple<decimal, decimal>> pricePoints= new List<Tuple<int, decimal>> discountRanges();

    public Pricing()
    {
        // These hard coded values would be replaced by logic to load from file.
        pricePoints.Add(Tuple.Create(7499, 5300));
        pricePoints.Add(Tuple.Create(7399, 5250));
        pricePoints.Add(Tuple.Create(7349, 5200));
        pricePoints.Add(Tuple.Create(7249, 5150));
        . . .
        pricePoints.Add(Tuple.Create(1049, 1000));
    }

    public decimal GetDiscount(QuoteData quoteData)
    {
        var price = TotalChapter7(quoteData);
        foreach(var point in pricePoints)
        {
            if(price >= point.Item1)
                return point.Item2;
        }
        // If we're here it implies there were no matching points
        return 0;
    }
}

如果您将代码构建到代码中,并且他们更改了代码,则您需要更改代码 将数据放在一个文件中,在运行时加载一次文件,他们可以更改价格,你只需要更改文件。

反驳“这里显然是商业规则”评论

不包括销售点的折扣(一个优惠2个,此商品优惠10%等),基本上有三种方式可以计算整体费用或折扣的折扣(任何一种都可以与首选客户折扣相结合) )。

  • 持平百分比(例如总是10%)
  • 不同价格点的不同百分比。
  • 不同价格点的不同平价(这是我们所看到的 在问题中)

客户决定使用哪一个(或多个)是业务规则,是的,规则需要在代码中表示。

但是,无论使用哪种规则,实际值都是数据,并且该数据应永远(禁止高度特殊情况)在代码中。

答案 2 :(得分:1)

也许这会有所帮助:

        List<Tuple<int, int>> _FeeToPrice = new List<Tuple<int, int>> { 
                new Tuple<int,int>(7499,5300),
                new Tuple<int,int>(7399,5250),
                            ...
                new Tuple<int,int>(1049,1000)
            };

        public decimal decDiscount(QuoteData quoteData)
        {
            var processedQuoteData = TotalChapter7(quoteData);
            var tuple = _FeeToPrice.FirstOrDefault(x => processedQuoteData >= x.Item1);
            if (tuple != null)
                return tuple.Item2;

            return 0;                           
        }

编辑: _FeeToPrice结构可以从文件或数据库或其他来源加载,这样可以更容易地更正返回值

答案 3 :(得分:1)

分析计算的工作公式如下:

int calcDiscount(int p)
{
  int s = (7500/50) - (p+1) / 50;
  int k = s / 3;
  int j = s % 3;

  return 5300 - 100*k - (j == 2 ? 50 : 0) 
}

工作测试用例(用Java编写):

for (p = 7499; p >= 1000; p -= 50)
{
  System.out.println (p+ " " + calcDiscount(p));
}

说明:首先你会发现当前价格从最大值(7499)开始有多少下降步骤,然后你知道你必须每三步降低贴现值100,但是如果你是当前三联的最后一步,你必须放弃它再增加50个。

答案 4 :(得分:0)

下面的伪代码:

Dictionary<Int, Int> getDiscounts(int startFee, int startDiscount, int endFee)
{
    Dictionary <Int, Int> quoteDictionary = new Dictionary<Int, Int> ();
    for(int i = 0; i++; startFee >= endFee)
    {
         startFee -= 50;
         if(i != 0)
         {
             startDiscount -= 50;
         }
         if(i == 2)
         {
             i = -1;
         }
         quoteDictionary[startFee] = startDiscount;
    }
    return quoteDictionary;
}

您可以这样称呼它:

Dictionary <Int, Int> prices = getDiscounts(7499, 5300, 1049);
int quote = TotalChapter7(quoteData);
int roundedQuote = quote - ((quote % 50) + 1);
int discountedFee = prices[roundedQuote];

答案 5 :(得分:0)

我不知道这是否适合您,但您可以使用字典,并按照上面示例中的降序对键进行排序。

我还没有测试过,但这样的事情可能有用:

public int GetNumber(int value)
{
    //initialize a dictionary to hold pairs of numbers
    var ranges = new SortedDictionary<int, int>
    {
        { 25, 250 },
        { 50, 500 },
        { 75, 750 }
    };

    //sort the dictionary in descending order and return the first value
    //that satisfies the condition
    return ranges.OrderByDescending(p => p.Key)
        .FirstOrDefault(p => value >= p.Key).Value;
}

答案 6 :(得分:-1)

尝试使用字典,试图做一个例子,但我不经常使用C#,所以纠正代码上不正确的东西,只是试着理解:

public decimal decDiscount(QuoteData quoteData)
{
    int result = 0; //if it doesn't match to any value on the dictionary it will return 0
    Dictionary<int, int> quotes = new Dictionary<int, int();
    quotes.add(7499, 5300); // not sure if that's how you add values to a dictionary
    ...
    quotes.add(1049, 1000);

    for(Entry<int, int> element in quotes) //not sure about the enhanced for too hehehe, not using C# for a while
    {
        if(TotalChapter7(quoteData) >= element.key() && element.value > result)
        {
            result = element.value(); //don't break cause you have to test the entire list for acurracy
        }
    }

    return result;
}