I want to extract a method from a working code. Inside this function, I can access records. But when returning, content of records is disposed. So I try to convert csv.GetRecords() to a List but I have an error message because records only contains methods Equals(),GetEnumerator(),GetHasCode(),GetType() & ToString(). I'm getting crazy :/ Does anyone can help me ? thanks.
private static IEnumerable<Animal> LoadFromCsvFile(/*[ExistingFile]*/ string fileName, Encoding encodingFormat, char separator)
{
using (var reader = new StreamReader(fileName))
using (var csv = new CsvReader(reader))
{
csv.Configuration.RegisterClassMap<AnimalClassMap>();
csv.Configuration.Delimiter = separator.ToString(CultureInfo.InvariantCulture);
csv.Configuration.Encoding = encodingFormat;
IEnumerable<Animal> records = csv.GetRecords<Animal>();
foreach (Animal rec in records)
{
Console.WriteLine($"{rec.FatherId}x{rec.MotherId} - {rec.Name} ({rec.Male}) breed {rec.Breed}");
}
return records;
}
}
GetRecords<Animal>()
doesn't get the records right away. It yields the results as you iterate the records. When you return records
before iterating them you find that that CsvReader
context has already been disposed and can no longer yield
the results. You can fix this by enumerating all of the records with .ToList()
before it leaves the using statement.
IEnumerable<SccAnimal> records = csv.GetRecords<Animal>().ToList();
The other option would be to make LoadFromCsvFile : IDisposable
and then dispose StreamReader
and CsvReader
in the Dispose()
method rather than putting them in a using
statement. In this case you would not be able to iterate them twice.
The GetRecords method will return an IEnumerable that will yield records. What this means is that only a single record is returned at a time as you iterate the records. That also means that only a small portion of the file is read into memory.