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

  • 本文关键字:计算 距离 于距离 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
  • 如果距离为63KM,则价格为90+(53*2(=90+106=196
  • 如果距离超过300公里,则功能应返回报价

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

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

您的问题看起来是责任链模式的一个很好的候选者。

其基本思想是,您有一个处理程序的链接列表,这些处理程序反过来决定他们是否可以进行计算或将任务传递给链中的下一个处理。

你可以在这里阅读更多关于

现在开始手头的任务。我创建了一个简单的例子,应该会给你主要的想法:

以下是您应该如何使用最终的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();
}
}

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

我复制了您的代码,并制作了一个函数,该函数接受List&距离:

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的内容,以防止混淆,或者可能同时具有StartingPrice&PricePerKm

最新更新