TB_COST.Data是我的DataTable,我正在遍历数据并计算一些字段。我想为每个计算使用单独的函数,但是我反复循环数据。我正在寻找避免重复的方法。
我试图循环一次数据并在内部调用函数,但是我认为以后很难修正错误。
public void CalculateCost()//this function getting called at a button onclick
{
try
{
CalculateProductPrice();
CalculateFreight();
}
catch(Exception ex)
{
ShowMessageBox(ex.ToString());
}
}
public void CalculateProductPrice()
{
decimal totalTonage = Convert.ToDecimal("0");
decimal totalPrice = Convert.ToDecimal("0");
decimal priceCarpiTonage = Convert.ToDecimal("0");
for(int i = 0; i < TB_COST.Data.Rows.Count; i++)
{
decimal containerTonage = Convert.ToDecimal(TB_COST.Data.Rows[i]["CONTON"].ToString());
totalTonage += containerTonage;
decimal price = Convert.ToDecimal(TB_COST.Data.Rows[i]["PROPRI"].ToString());
totalPrice += price;
priceCarpiTonage += Convert.ToDecimal(containerTonage) * price;
}
decimal productPrice = priceCarpiTonage/totalTonage;
productPrice = (Math.Round(productPrice, 2, MidpointRounding.AwayFromZero));
//ShowMessageBox(totalPrice + " " + priceCarpiTonage + " " + productPrice);
T_PROP.Text = productPrice.ToString();
T_TOTN.Text = totalTonage.ToString();
}
public void CalculateFreight()
{
decimal totalFreight = Convert.ToDecimal("0");
for(int i = 0; i < TB_COST.Data.Rows.Count; i++)
{
decimal decimalFreightPrice = Convert.ToDecimal(TB_COST.Data.Rows[i]["CONPRI"].ToString());
decimal containerTonnage = Convert.ToDecimal(TB_COST.Data.Rows[i]["CONTON"].ToString());
decimal decimalFreightBoluContainerTonnage = decimalFreightPrice/containerTonnage;
totalFreight += decimalFreightBoluContainerTonnage;
}
//ShowMessageBox(totalFreight.ToString());
totalFreight = (Math.Round(totalFreight, 2, MidpointRounding.AwayFromZero));
T_FREG.Text = totalFreight.ToString();
}
答案 0 :(得分:1)
根据您的评论和mr springers's answer,我认为您只需要添加一些辅助函数并在for
中调用它们即可。
注意:要使其可以进行单元测试,需要一些有关TB_COST
的信息。那么签名将为public CalculationsResult PerformCalculations(???? TB_COST)
,并且不会与UI交互。
public void PerformCalculations()//this function getting called at a button onclick
{
try
{
CalculationsResult calculations = new CalculationsResult();
for(int i = 0; i < TB_COST.Data.Rows.Count; i++)
{
DoMyCalculation(calculations, TB_COST.Data.Rows[i]);
// Call other calculations
}
decimal productPrice = calculations.PriceCarpiTonage / calculations.TotalTonage;
productPrice = (Math.Round(productPrice, 2, MidpointRounding.AwayFromZero));
T_PROP.Text = productPrice.ToString();
T_TOTN.Text = totalTonage.ToString();
totalFreight = (Math.Round(totalFreight, 2, MidpointRounding.AwayFromZero));
T_FREG.Text = totalFreight.ToString();
}
catch(Exception ex)
{
ShowMessageBox(ex.ToString());
}
}
private void DoMyCalculation(CalculationsResult calculations, DataRow row)
{
calculations.TotalPrice += (decimal)row["MyColumn"];
}
public class CalculationsResult
{
public decimal TotalTonage { get; set; }
public decimal TotalPrice { get; set; }
public decimal PriceCarpiTonage { get; set; }
}
答案 1 :(得分:0)
最简单的方法是将两个方法合并为一个大方法:
此后,您会遇到方法太大而难以维护的问题。因此,您必须再次重构此方法。
您现在应该更改此方法,以遵守可靠的原则。 https://medium.com/@mirzafarrukh13/solid-design-principles-c-de157c500425
第一步,您应该创建一个新对象,该对象代表数据表的一行。之后,您应该创建一个新方法来将数据从数据表加载到该对象的列表中。
public class TbCost {
public decimal Conton {get;set;}
public decimal ProPri {get;set;}
public decimal ConPri {get;set;}
public decimal GetPriceCarpiTonage() {
return Conton * ProPri;
}
public decimal GetFreightBoluContainerTonnage() {
return ConPri / Conton;
}
}
public void CalculateCost()//this function getting called at a button onclick
{
try
{
decimal totalTonage = 0m;
decimal totalPrice = 0m;
decimal priceCarpiTonage = 0m;
decimal totalFreight = 0m;
IList<TbCost> tbCosts = ReadTbCosts(TB_COST.Data.Rows);
foreach (TbCost tbCost in tbCosts)
{
totalTonage += tbCost.Conton;
totalPrice += tbCost.ProPri;
priceCarpiTonage += tbCost.GetPriceCarpiTonage();
totalFreight += tbCost.GetFreightBoluContainerTonnage();
}
T_PROP.Text = Round(priceCarpiTonage/totalTonage);
T_TOTN.Text = totalTonage.ToString();
T_FREG.Text = Round(totalFreight);
}
catch(Exception ex)
{
ShowMessageBox(ex.ToString());
}
}
// This method should be moved to a sperate class
private string Round(decimal decimalValue) {
return (Math.Round(decimalValue, 2, MidpointRounding.AwayFromZero)).ToString();
}