Search code examples
c#csvhelper

CsvReader.ColumnCount always returns 0, different from CsvReader.Parser.Count


Consider the following code:

var sb = new StringBuilder();
sb.Append(@"Title,Something");
sb.AppendLine();
sb.Append(@"hello world,abc");
sb.AppendLine();


using var stringReader = new StringReader(sb.ToString());
using var csvReader = new CsvReader(stringReader, CultureInfo.InvariantCulture);

int lineIndex = 0;

while (csvReader.Read())
{
    if (lineIndex == 0)
    {
        csvReader.ReadHeader();
        Debug.WriteLine($"header column count: {csvReader.ColumnCount} and {csvReader.Parser.Count}");
    }
    else
    {
        var foo = csvReader.GetRecord<Foo>();
        Debug.WriteLine($"data column count: {csvReader.ColumnCount} and {csvReader.Parser.Count}");

    }

    lineIndex++;
}

class Foo
{
    public string Title { get; set; } = null!;
    public string Something { get; set; } = null!;
}

This outputs:

header column count: 0 and 2
data column count: 0 and 2

I am confused about the both zeros, respectively csvReader.ColumnCount returning 0. Anyone can explain why? The documentation states "This should match IParser.Count". Well, should, but does not - but why? Using latest stable CsvHelper 30.0.1.


Solution

  • Currently you have to set DetectColumnCountChanges = true on CsvConfiguration in order to get the correct count from csvReader.ColumnCount.

    var sb = new StringBuilder();
    sb.AppendLine(@"Title,Something");
    sb.AppendLine(@"hello world,abc");
    
    var config = new CsvConfiguration(CultureInfo.InvariantCulture){
        DetectColumnCountChanges = true
    };
    
    using var stringReader = new StringReader(sb.ToString());
    using var csvReader = new CsvReader(stringReader, config);
    
    int lineIndex = 0;
    
    while (csvReader.Read())
    {
        if (lineIndex == 0)
        {
            csvReader.ReadHeader();
            Debug.WriteLine($"header column count: {csvReader.ColumnCount} and {csvReader.Parser.Count}");
        }
        else
        {
            var foo = csvReader.GetRecord<Foo>();
            Debug.WriteLine($"data column count: {csvReader.ColumnCount} and {csvReader.Parser.Count}");
    
        }
    
        lineIndex++;
    }
    
    class Foo
    {
        public string Title { get; set; } = null!;
        public string Something { get; set; } = null!;
    }