Using reflections to add List<T> C#

#1

I am reading a file which is like

HDR …
LIN …
LIN …
LIN …
HDR …
LIN …
LIN …

Now LIN corresponds to line items and belong to the HDR above.

Also, mapping for the data comes from xml which has already been deserilized. This has the mappings like which property to store the data in Header or LineItems class, how many chars to pick, if it is required or not etc.

The model to store data looks like

public class Header
{
    public string Id { get; set; }
    public string Description { get; set; }
    public List<Item> LineItems { get; set; }
}

I have a generic function which reads this data into List We have different files each having different mapping. For this reason need to use a generic function to load data before processing it.

I need help with

  • #1 in the below function - is it correct way to make sure that property LineItems is not null before adding the LineItem to it?

  • How to do #2 in below function, using reflection to add lineItem to data[headindex-1].LineItems.Add(...)?

public static List<H> ReadFile<H, I>(ConfigTypeUploadXml uploadConfig, string fileNamePath, ref string errMsg) where H : new() where I : new()
{
    // we'll use reflections to add LineItems to data
    var properties = typeof(H).GetProperties();

    // read the file line by line and add to data. 
    var data = new List<H>();
    var headIndex = 0;
    var lineIndex = 1;

    foreach (string line in File.ReadAllLines(fileNamePath))
    {

        // read HDR line
        if (line.StartsWith("HDR"))
        {
            var header = ReadHeaderLine<H>(uploadConfig, line, errMsg);
            data.Add(header);
            headIndex += 1;
        }

        // read LIN line
        if (line.StartsWith("LIN"))
        {
            I lineItem = ReadItemLine<I>(uploadConfig, line, errMsg);

            foreach (PropertyInfo p in properties)
            {
                if (p.Name != "LineItems")
                    continue;

                //1) if items is null then create the object
                List<I> items = p.GetValue(data[headIndex - 1], null);
                if (items == null)
                    p.SetValue(data[headIndex - 1], new List<I>());
					
		//2) add line item to data[headIndex - 1]
				
            }
        }

        lineIndex += 1;
    }

    return data;
}
#2

I had changed the function a little bit… This isn’t tested since i am waiting on some additional info. The actual app is in vb.net so converting the code didn’t follow the best practices, plz ignore that. For simplicity, i have removed validations as well.

public static List<THeader> ReadUpload850File<THeader, TItem>(ConfigTypeUploadXml uploadConfig, string fileNamePath, ref string errMsg)
     where THeader : new()
     where TItem : new()
{
    
    // we'll use reflections to add LineItems to data
    PropertyInfo[] properties = typeof(THeader).GetProperties();

    // read the file line by line
    List<THeader> data = new List<THeader>();
    int headIndex = 0;
    int lineIndex = 1;

    foreach (string line in File.ReadAllLines(fileNamePath))
    {
        // read HDR line
        if (line.StartsWith("HDR"))
        {
            THeader header = ReadHeaderLine<THeader>(uploadConfig, line, errMsg);
            data.Add(header);
            headIndex += 1;
        }

        // read LIN line
        if (line.StartsWith("LIN"))
        {
            TItem lineItem = ReadItemLine<TItem>(uploadConfig, line, errMsg);
            THeader header = data[data.Count - 1];
            PropertyInfo lineItemsProperty = header.GetType().GetProperty("LineItems");
            // Dim items As Object = lineItemsProperty.GetValue(header)
            // If items Is Nothing Then lineItemsProperty.SetValue(header, Nothing)
            IList lineItems = lineItemsProperty.GetValue(header) as IList;
if(lineItems == null) lineItems = new List<TItem>();
            lineItems.Add(lineItem);
lineItemsProperty.SetValue(header, lineItems);
        }

        lineIndex += 1;
    }

    return data;
}
#3

I don’t see the relevant code.

I don’t see that either. I searched for data[headindex-1] and the only place the browser finds that is in the question (as quoted) only.

#4

@SamuelCalifornia
Question has #1 and #2 but my second post is the implemented solution.

#5

This is for an EDI file, right? I tried to work with EDI files a long time ago. Unfortunately the customer did not want to pay for it so I gave up. The organization that uses the format was going to discontinue working with the company if they did not comply but they did not want to pay to get into compliance.

As I recall the organization that uses the format will help if you need help. Also, are you sure there are not examples?

Does that mean the problem is solved?

#6

It is EDI and yes the problem is solved. I am not happy since i have to work with reflections. The mapping to read the text file parsing and which property to populate the data with is coming from XML. My second issue is that the text file has multiple data like following where HDR is parent row and LIN right after that are children of the HDR.
HDR …
LIN …
LIN …
HDR …
LIN …
LIN…