Search code examples
c#generic-listordinal

How to access public properties of a List<class> by their ordinal position


I have public properties of a class and my output detail line is being written like this:

public static long OutputListToFile(StreamWriter writer, List<DocMetaData> listData)
    {
        StringBuilder md = new StringBuilder();
        int rowcount = 0;
        foreach (var c in listData)
        {
            md.Append(c.Section); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.DocClass); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.Meeting); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.Agency); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.Country); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.Comment); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.Title); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.Folder); md.Append(DocMetaData.SEPARATOR);
            md.Append(c.File); md.Append(DocMetaData.CARRIAGE_RETURN);
            try
            {
                writer.WriteLine(md.ToString());
                rowcount++;
            }
            catch (Exception ex)
            {
                log.Fatal("Error in OutputListToFile:\r\n", ex);
            }
        }
        return rowcount;
    }

The md.Append statements currently have to be placed in the above exact order so as to match with the routine that writes the very first line:

private void OutputColumnNamesAsFirstLine(StreamWriter writer)
    {
        StringBuilder md = new StringBuilder();
        PropertyInfo[] columns;
        columns = typeof(DocMetaData).GetProperties(BindingFlags.Public |
                                                      BindingFlags.Instance);
        int i = 0;
        foreach (var columnName in columns)
        {
            i++;
            md.Append(columnName.Name); md.Append(DocMetaData.SEPARATOR);
        }
        writer.WriteLine(md.ToString());
    }

Is there a way the foreach loop in OutputListToFile could be rewritten such that I can eliminate this ordering dependency. Here is a snippet of the DocMetaData class:

 public class DocMetaData
{
    public const string SEPARATOR = "\t";       // horizontal tab is delimiter
    public const string CARRIAGE_RETURN = "\r";

    public string Section { get; set; }
    public string DocClass { get; set; }
    public string Meeting { get; set; }
    public string Agency { get; set; }
    public string Country { get; set; }
    public string Comment { get; set; }
    public string Title { get; set; }
    public string Folder { get; set; }
    public string File { get; set; }

Solution

  • I'm not sure this is what you want, but if you want to write the content of all properties in the same order they are in column, you can just use that:

    foreach (var c in listData)
    {
        foreach (var column in columns)
        {
            md.Append(column.GetValue(c, null));
        }
    }
    

    This code doesn't use the separator and terminator as your original code, but I'm sure you can easily fix that.