0

I have two methods they are exactly the same except the first parameter.I don't want to repeat the duplicate code. I was wondering how can we refactor the following code using generic parameters.

First method

 private Dictionary<List<string>, List<string>> GetFinancialLtmDataSet(List<sp_get_company_balance_sheet_amount_ltm_Result> itemResult, int neededyear)
    {
        var requestedData =
            itemResult.OrderByDescending(x => x.date.Year).Take(neededyear).Select(x => new { date = x.date.Date });

        var addFields = new List<string>();
        var dataSet = new Dictionary<List<string>, List<string>>();
        int counter = 0;
        foreach (var itemy in requestedData)
        {
            var skipvalue = itemResult.Skip(counter);
            var columns = skipvalue.OrderBy(x => itemy.date).ToList();
            var cc = columns.First();
            counter++;
            var properties =
                cc.GetType()
                    .GetProperties()
                    .Select(x => new { Name = x.Name, Value = x.SetMethod, a = x.GetValue(cc, null) })
                    .ToList();

            foreach (var property in properties)
            {
                addFields.Add(property.Name);
                if (property.a != null)
                {
                    dataSet.Add(new List<string> { property.Name }, new List<string> { property.a.ToString() });
                }
            }
        }
        return dataSet;
    }

Second method

private Dictionary<List<string>, List<string>> GetFinancialQuartelyDataSet(List<sp_get_company_balance_sheet_amount_quaterly_Result> itemResult, int neededyear)
    {
        var requestedData =
            itemResult.OrderByDescending(x => x.date.Year).Take(neededyear).Select(x => new { date = x.date.Date });

        var addFields = new List<string>();
        var dataSet = new Dictionary<List<string>, List<string>>();
        int counter = 0;
        foreach (var itemy in requestedData)
        {
            var skipvalue = itemResult.Skip(counter);
            var columns = skipvalue.OrderBy(x => itemy.date).ToList();
            var cc = columns.First();
            counter++;
            var properties =
                cc.GetType()
                    .GetProperties()
                    .Select(x => new { Name = x.Name, Value = x.SetMethod, a = x.GetValue(cc, null) })
                    .ToList();

            foreach (var property in properties)
            {
                addFields.Add(property.Name);
                if (property.a != null)
                {
                    dataSet.Add(new List<string> { property.Name }, new List<string> { property.a.ToString() });
                }
            }
        }
        return dataSet;
    }

I have created a following method to make it generic but not been able to get the final implementation any suggestion appreciated.

private List<T> GetFinancialReport<T>(List<T> data, int neededyear)
  {

       //what should I return from here 
        return data;
  }

and would like to use the above method  like this


 var balancesheetResult=balancesheet.ToList();
 var testData = GetFinancialReport<BalanceSheet_sp>(balancesheetResult, 5);

var cashflowresult=cashflow.ToList();
var testData1 = GetFinancialReport<CahsFlow_sp>(cashflowresult, 10);
6
  • 2
    The return type should then be Dictionary<List<string>, List<string>>, am I right? Also you could use an interface here instead of a generic parameter if the needed properties are common. Commented Jun 29, 2015 at 13:47
  • Do they (CahsFlow_sp and BalanceShit_sp) have something in common? Some base class/interface? No? Then how would method know what to select and what to populate? Commented Jun 29, 2015 at 13:48
  • Yes the return type should be Dictionary<List<string>, List<string>> Commented Jun 29, 2015 at 13:48
  • @Sinatr : Currently they don't have any common interface or base class. Cashflow_sp and balancesheet_sp are the stored procedure. The fields are common on both Cashflow_sp and balancesheet_sp but there is no model defined at the moment. I am directly calling the stored procedure on my method. Commented Jun 29, 2015 at 13:51
  • 1
    @user3922960 So, it means you have auto-generated classes (sp_get_company_balance_sheet_amount_quaterly_Result, .....) which you can extend adding сommon interface (IBalance), because they are partial. More information here: msdn.microsoft.com/en-us/library/vstudio/… Commented Jun 29, 2015 at 14:34

1 Answer 1

1

From what is shown above the objects (at least the properties involved) match. So you could code against an interface here:

private Dictionary<List<string>, List<string>> GetFinancialReport(List<IBalance>, int neededyear) 
{
    ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

thank you for the pointers Could you please give me more detail about what should be inside IBalance Interface?
@user3922960 I think it should look like: public interface IBalance { DateTime date {get; set;} }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.