Csvhelper: Object reference not set to an instance of an object.

Created on 5 Oct 2018  ·  8Comments  ·  Source: JoshClose/CsvHelper

@JoshClose

private IEnumerable<Participant> ReadCSV(string path)
        {
            IEnumerable<Participant> records = null;
            using (var sr = new StreamReader(path))
            {
                var reader = new CsvReader(sr);
                reader.Configuration.HasHeaderRecord = false;
                reader.Read();
                records = reader.GetRecords<Participant>();
                sr.Close();
            }
            return records;
        }

when the csv reader arrived at end of the line of csv, an error appears like this:

System.NullReferenceException: Object reference not set to an instance of an object.
   at CsvHelper.CsvReader.<GetRecords>d__63`1.MoveNext()
   at Reader.testForm..ctor(IEnumerable`1 peserta) in C:\Users\SIGI-PC\Documents\Visual Studio 2015\Projects\Reader\Reader\testForm.cs:line 28
Exception thrown: 'System.NullReferenceException' in Reader.exe

Most helpful comment

You're closing the stream before you've read the records. GetRecords<T> returns an IEnumerable<T> that will yield records. What that means is it doesn't actually pull the records until you access them. If you're returning the IEnumerable<T>, you can't close the reader because it needs to be used to get the records.

All 8 comments

You're closing the stream before you've read the records. GetRecords<T> returns an IEnumerable<T> that will yield records. What that means is it doesn't actually pull the records until you access them. If you're returning the IEnumerable<T>, you can't close the reader because it needs to be used to get the records.

@JoshClose, you should change the code sample in the getting started page where it says:

C# using (var reader = new StreamReader("path\\to\\file.csv")) using (var csv = new CsvReader(reader)) { var records = csv.GetRecords<Foo>(); }

This won't work when using records outside of the using blocks. I just did that same mistake.

What should I add to the sample? This is fundamentals of how a using block works. Should I add a blurb about that in the text below the example?

C# using (var reader = new StreamReader("path\\to\\file.csv")) using (var csv = new CsvReader(reader)) { foreach (var record in csv.GetRecords<Foo>()) { // do something with record } }

@FObermaier I think @JoshClose 's intention was to imply that by putting the declaration var = records _inside_ the using. By declaring it there, the variable records cannot be used outside the using scope anyway (regardless whether it is using yield or not)

C# List<Foo> list = new List<Foo>(); using (var reader = new StreamReader(fileName)) { var csv = new CsvReader(reader,CultureInfo.InvariantCulture); while (csv.Read()) { var item = csv.GetRecord<Foo>(); list.Add(item); } return list; }
Like this ,It is OK!

   List<Foo> list = new List<Foo>();
   using (var reader = new StreamReader(fileName))
    {
            var csv = new CsvReader(reader,CultureInfo.InvariantCulture);
             while (csv.Read())
             {
                   var item = csv.GetRecord<Foo>();
                   list.Add(item);
             }
            return list;
     }

Like this ,It is OK!

ToList() if all you need is to execute the query immediately and return a List (with C# 8 simplified using syntax).

using var reader = new StreamReader(filePath);
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
return csv.GetRecords<Foo>().ToList();
Was this page helpful?
0 / 5 - 0 ratings