Как я могу избежать зацикливания одних и тех же данных - PullRequest
0 голосов
/ 08 июля 2019

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();
    }

Ответы [ 2 ]

1 голос
/ 08 июля 2019

На основании ваших комментариев и ответа г-на Спрингера Я думаю, вам просто нужно добавить некоторые вспомогательные функции и вызвать их внутри вашего for.

Примечание: чтобы сделать его тестируемым на устройстве, потребуется некоторая информация о том, что такое TB_COST. Тогда подпись будет public CalculationsResult PerformCalculations(???? TB_COST) и не будет взаимодействовать с пользовательским интерфейсом.

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; }
}
0 голосов
/ 08 июля 2019

Самый простой способ - объединить оба метода в один большой метод:

После этого у вас возникает проблема, заключающаяся в том, что метод стал слишком большим и его нелегко поддерживать. Таким образом, вы должны рефакторинг этого метода снова.

Теперь вы должны изменить этот метод, чтобы уважать твердые принципы. 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...