loop over fields of a C# object

by knot22   Last Updated December 06, 2018 14:26 PM

In a project there is a reporting class as follows:

public class ReportRowDataContract
{   
    public ReportDataDataContract ReportData1 { get; set; }

    public ReportDataDataContract ReportData2 { get; set; }

    public ReportDataDataContract ReportData3 { get; set; }

    public ReportDataDataContract ReportData4 { get; set; }

    public ReportDataDataContract ReportData5 { get; set; }

    public ReportDataDataContract ReportData6 { get; set; }        
}

Then there is a method that works with objects from the above class. Here is the first part of this method:

public ReportGrid(List<ReportRowDataContract> items , List<ReportDataDataContract> summaryData)
            : base(items)
        {

                passedInSummaryData = summaryData;

                if (items[0].ReportData1 != null)
                {
                    if (items[0].ReportData1.DecimalValue != null)
                    {

                        Columns.Add(m => m.ReportData1.DecimalValue).Titled(items[0].ReportData1.Name).Encoded(false).
                            Sanitized(false).RenderValueAs(
                                m => (string.IsNullOrEmpty(@m.ReportData1.DisplayFormat)) ? Convert.ToDecimal(@m.ReportData1.DecimalValue).ToString("N") : Convert.ToDecimal(@m.ReportData1.DecimalValue).ToString(@m.ReportData1.DisplayFormat));

                        if (items[0].ReportData1.SumValue || items[0].ReportData1.AvgValue)
                        {
                            displaySummary = true;
                            SummaryData.Add(
                                new ReportDataDataContract
                                    {
                                        Name = items[0].ReportData1.Name,
                                        AvgValue = items[0].ReportData1.AvgValue,
                                        DecimalValue = 0
                                    });
                        }
                    }
                    else if (items[0].ReportData1.IntValue != null)
                    {
                        Columns.Add(m => m.ReportData1.IntValue).Titled(items[0].ReportData1.Name);
                        if (items[0].ReportData1.SumValue || items[0].ReportData1.AvgValue)
                        {
                            displaySummary = true;
                            SummaryData.Add(
                                new ReportDataDataContract
                                    {
                                        Name = items[0].ReportData1.Name,
                                        AvgValue = items[0].ReportData1.AvgValue,
                                        IntValue = 0
                                    });
                        }
                    }
                    else
                    {
                        Columns.Add(m => m.ReportData1.StringValue).Titled(items[0].ReportData1.Name);
                    }
                }
                if (items[0].ReportData2 != null)
                {
                    if (items[0].ReportData2.DecimalValue != null)
                    {
                    Columns.Add(m => m.ReportData2.DecimalValue).Titled(items[0].ReportData2.Name).Encoded(false).
                       Sanitized(false).RenderValueAs(
                           m => (string.IsNullOrEmpty(@m.ReportData2.DisplayFormat)) ? Convert.ToDecimal(@m.ReportData2.DecimalValue).ToString("N") : Convert.ToDecimal(@m.ReportData2.DecimalValue).ToString(@m.ReportData1.DisplayFormat));

                    if (items[0].ReportData2.SumValue || items[0].ReportData2.AvgValue)
                        {
                            displaySummary = true;
                            SummaryData.Add(
                                new ReportDataDataContract
                                    {
                                        Name = items[0].ReportData2.Name,
                                        AvgValue = items[0].ReportData2.AvgValue,
                                        DecimalValue = 0
                                    });
                        }
                    }
                    else if (items[0].ReportData2.IntValue != null)
                    {
                        Columns.Add(m => m.ReportData2.IntValue).Titled(items[0].ReportData2.Name);
                        if (items[0].ReportData2.SumValue || items[0].ReportData2.AvgValue)
                        {
                            displaySummary = true;
                            SummaryData.Add(
                                new ReportDataDataContract
                                    {
                                        Name = items[0].ReportData2.Name,
                                        AvgValue = items[0].ReportData2.AvgValue,
                                        IntValue = 0
                                    });
                        }
                    }
                    else
                    {
                        Columns.Add(m => m.ReportData2.StringValue).Titled(items[0].ReportData2.Name);
                    }

                }

This method consists of code that repeats itself out to ReportData6, changing only the ReportData field name with each repetition. Is there a way that this method can be rewritten to process each ReportData field by looping somehow? Besides making for a shorter method, this would be extremely useful to have in order to avoid manually updating the method if additional ReportData fields need to be added to the ReportRowDataContract class in the future.

Tags : c#


Answers 2


Just put report datas into array and iterate through it:

public class ReportRowDataContract
{   
    public IEnumerable<ReportDataDataContract> ReportData { get; set; }  
}

foreach(var data in items[0].ReportData)
{
   if (data != null)
   {
      ...
   }
}
Fabjan
Fabjan
December 06, 2018 14:24 PM

If you can, you should simply change the ReportRowDataContract to only hold a single property that is an array of ReportDataDataContract. Then you can use a simple loop for each of the data contracts.

If you can't change the ReportRowDataContract table, you could use a method that takes in an argument of type ReportDataDataContract and have all the repeated code there - and just call it one time for each property.

Zohar Peled
Zohar Peled
December 06, 2018 14:24 PM

Related Questions