C#中基于距离的价格计算

时间:2020-09-26 09:55:31

标签: c#

我必须根据距离和公里数来计算价格。有人可以帮我实现目标吗?我的数组如下:

List<PriceStructure> priceStructure = new List<PriceStructure>()
{
    new PriceStructure { FromKm = 1, ToKm = 10, Price = 90, IsMinimum = true, IsContact = false },
    new PriceStructure { FromKm = 11, ToKm = 20, Price = 7, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 21, ToKm = 30, Price = 6, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 31, ToKm = 40, Price = 5, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 41, ToKm = 50, Price = 4, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 51, ToKm = 60, Price = 3, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 61, ToKm = 70, Price = 2, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 71, ToKm = 300, Price = 1.50M, IsMinimum = false, IsContact = false },
    new PriceStructure { FromKm = 301, ToKm = 0, Price = 0, IsMinimum = false, IsContact = true }
};

如果距离在1到10公里之间,则最低价格为90。如果距离大于10,则每公里将根据每公里每行(从11公里开始)中在数组中定义的价格计算得出。

例如:

  • 如果距离为8公里,则价格为90
  • 如果距离为15公里,则价格应为90 +(5x7)= 90 + 35 = 125
  • 如果距离为39公里,则价格应为90 +(29x5)= 90 + 145 = 235
  • 如果距离为63公里,则价格应为90 +(53 * 2)= 90 + 106 = 196
  • 如果距离超过300公里,则功能应返回报价。

3 个答案:

答案 0 :(得分:0)

您可以创建一个函数来反映您已经完成的计算,例如:

int CalculatePrice(PriceStructure ps) {

    int distance = ps.ToKm - ps.FromKm;  

    if(distance < 10) {
       return 90;
    }

    int price = 90 + ((distance - 10) * ps.Price);

    return price;

} 

然后,您可以遍历priceStructure并使用列表中的每个项目调用函数。

为改进代码,您可以将最小距离视为常量或至少一个变量。我还建议将PriceStructure中的Price属性重命名为可以更好地表示实际值的东西,听起来像PricePerKm

答案 1 :(得分:0)

您的问题似乎很适合采用责任链模式。

基本上,您的想法是您有一个处理程序的链接列表,这些处理程序又决定了它们可以执行计算还是将任务传递给链中的下一个处理程序。

您可以详细了解here

现在完成手头的任务。我创建了一个简单的示例,应该可以为您提供主要思想:

这是您应使用最终API的方式:

var calculator = new PriceCalculator();
calculator.RegisterNext(new CalculationHandler(0, 8, (dist) => 90M));
calculator.RegisterNext(new CalculationHandler(9, 15, (dist) => 125M));
calculator.RegisterNext(new CalculationHandler(16, 39, (dist) => 235M));
calculator.RegisterNext(new CalculationHandler(40, 63, (dist) => 196M));
calculator.RegisterNext(new CalculationHandler(64, int.MaxValue, (dist) => 1000));

var km = 29;
Console.WriteLine("Price for {0}km is: {1}", km, calculator.Calculate(km));

PriceCalculator.cs

public class PriceCalculator
{
    private ICalculatorHandler _handler;

    public PriceResult Calculate(int distance)
    {
        return _handler.Calculate(distance);
    }

    public void RegisterNext(ICalculatorHandler handler)
    {
        if (_handler == null)
        {
            _handler = handler;
        }
        else
        {
            _handler.RegisterNext(handler);
        }
    }
}

ICalculationHandler.cs

public interface ICalculatorHandler
{
    PriceResult Calculate(int distance);
    void RegisterNext(ICalculatorHandler handler);
}

CalculationHandler.cs

public class CalculationHandler : ICalculatorHandler
{
    private readonly int _minDist;
    private readonly int _maxDist;
    private readonly Func<int, decimal> _formula;
    private ICalculatorHandler _next;

    public CalculationHandler(int minDist, int maxDist, Func<int, decimal> formula)
    {
        _minDist = minDist;
        _maxDist = maxDist;
        _formula = formula;
        _next = null;
    }

    public PriceResult Calculate(int distance)
    {
        if (!(_minDist <= distance && distance <= _maxDist))
        {
            if(_next != null)
                return _next.Calculate(distance);

            return PriceResult.Invalid;
        }

        return new PriceResult(_formula(distance));
    }

    public void RegisterNext(ICalculatorHandler handler)
    {
        if (_next == null)
        {
            _next = handler;
        }
        else
        {
            _next.RegisterNext(handler);
        }
    }
}

PriceResult.cs

public class PriceResult
{
    public static PriceResult Invalid = new PriceResult(int.MaxValue);

    public decimal Value { get; }

    public PriceResult(decimal value)
    {
        Value = value;
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}

注意:我不知道这里的上下文,但是我建议您进行数据验证和空检查,不要将decimal用作一般价格类型。我的 PriceResult类是存根,我怀疑您的类应该更多 抛光。这段代码只是获得主要思想的示例。

答案 2 :(得分:-1)

我复制了您的代码,并创建了一个包含列表和距离的函数:

public static decimal CaluclatePrice(int distance, List<PriceStructure> priceStructures)
{
    decimal minimumPrice = priceStructures.Find(p => p.IsMinimum == true).Price;
    PriceStructure ps = priceStructures.Find(p => distance >= p.FromKm && distance <= p.ToKm);

    if (ps.IsMinimum)
        return ps.Price;
    else
        return (distance - 10) * ps.Price  + minimumPrice;

}

就像其他评论中提到的那样,您应该将PriceStructure.Price变量重命名为PricePerKm之类的名称,以防止混淆,或者同时使用StartingPricePricePerKm

相关问题