Convert IEnumerable to CSV
I modified the formatting part for better readability and maintainability, at the cost of lower performance:

var columns = new Dictionary&lt;string, Func&lt;Reads, object&gt;&gt;
{
    ["Read Date"] = x =&gt; x.CurrentReadDate,
    ["Device"] = x =&gt; x.DeviceKey,

    ["Suffix"] = x =&gt; x.Suffix,
    ["Read"] = x =&gt; x.CurrentReadRawValue,
    // add the rest of headers/property selectors below
};
//var format = "{0},{1} : {2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25},{26},{27}";
var format = "{0}{1} : " + string.Join(",", columns.Select((_, i) =&gt; $"{{{i}}}").Skip(2));

var csv = new StringBuilder()
    .AppendFormat(format, columns.Keys.ToArray())
    .AppendLine();
foreach (var read in reads)
{
    var values = columns.Values.Select(selector =&gt; selector(read));
    csv
        .AppendFormat(format, values.ToArray())
        .AppendLine();
}


The advantage of this approach is that you can add/move/remove the columns without having to worry about updating the header and the format, and if they are kept in sync or not.

Note:


You can also revert to the constant format if it becomes more complex.
The property selector can be chained if you need special format on individual property, like: x =&gt; x.CurrentReadDate.ToString("yyyyMMddThhmm")