C# CSV Parse List Field

In this example, we are going to parse a CSV file that contains a list of values in a single field. Suppose we have the following CSV to parse:


NAME,DATES
ES1 Index,01/01/2023;05/01/2023;12/26/2023
...

Let's create a record class to hold the parsed data first:

public readonly record struct CsvRecord {

    [Name("NAME")]
    public readonly string Name { get; init; }

    [Name("DATES")]
    public IReadOnlyCollection<DateOnly> Dates { get; init; }

}

To parse the CSV field into a collection in C#, we need to create a special class map in CsvHelper:

public sealed class CsvRecordMap: ClassMap<CsvRecord> {

    public CsvRecordMap() {
        AutoMap(CultureInfo.InvariantCulture);
        Map(m => m.Dates).Convert(row => ParseDates(row.Row.GetField("DATES")));
    }

    private static IReadOnlyCollection<DateOnly> ParseDates(string s) {
        var dates = return s.Split(";")
            .Select(a => DateOnly.ParseExact(a, "MM/dd/yyy", null))
            .ToImmutableList();
        return dates;
    }

}

To use this class map, we register it when we read the CSV, for example:

using var csv = new CsvReader(stream, CultureInfo.InvariantCulture));
csv.Context.RegisterClassMap<CsvRecordMap>();
return csv.GetRecords<CsvRecord>().ToImmutableList();

See CSV Parsing TypeConverter article for more details.