Working with CSV in C# (.NET): Tool Overview and Examples
CSV (Comma-Separated Values) is one of the most common formats for exchanging tabular data. In the C# (.NET) ecosystem, there are several reliable ways to work with this format: from built-in tools to powerful third-party libraries. In this article, we will review the main approaches and best practices.
Why You Shouldn't Write a CSV Parser Manually?
The CSV format seems simple at first glance, but in practice it contains many nuances: quote escaping, commas inside fields, different delimiters, newline characters in values. Using ready-made libraries saves you headaches and edge case handling.
CsvHelper Library — The Gold Standard
CsvHelper is the most popular library for working with CSV in .NET. It supports mapping to POCO classes, streaming reads, delimiter and encoding configuration.
Installation via NuGet:
Install-Package CsvHelperExample of Reading CSV into a List of Objects
using CsvHelper;using System.Globalization;
public class User{ public int Id { get; set; } public string Name { get; set; } public string Email { get; set; }}
var users = new List<User>();using (var reader = new StreamReader("users.csv"))using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)){ users = csv.GetRecords<User>().ToList();}Example of Writing CSV from a Collection
using (var writer = new StreamWriter("output.csv"))using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)){ csv.WriteRecords(users);}Built-in Parser: TextFieldParser (Microsoft.VisualBasic)
If you don't want to add external dependencies, .NET has a built-in TextFieldParser from the Microsoft.VisualBasic.FileIO namespace. It is available in .NET Framework and .NET Core/.NET 5+ (requires installing the Microsoft.VisualBasic package).
Example of Using TextFieldParser
using Microsoft.VisualBasic.FileIO;
using (var parser = new TextFieldParser("data.csv")){ parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); parser.HasFieldsEnclosedInQuotes = true;
while (!parser.EndOfData) { string[] fields = parser.ReadFields(); Console.WriteLine(string.Join(" | ", fields)); }}Pros: no third-party libraries required. Cons: less flexible than CsvHelper, no automatic class mapping.
Working with Large Files: Streaming Processing
When working with CSV files larger than 100 MB, it is important to avoid loading the entire file into memory. Both libraries support streaming processing:
- CsvHelper — use
GetRecords<T>()in aforeachloop without calling.ToList(). - TextFieldParser — reads line by line, which is also efficient.
Example of Streaming Reading with CsvHelper
using (var reader = new StreamReader("large.csv"))using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)){ foreach (var record in csv.GetRecords<User>()) { ProcessUser(record); // process one by one }}Error Handling and Data Validation
When importing CSV, data may be invalid. CsvHelper allows configuring error handling through events:
csv.Configuration.BadDataFound = context =>{ Console.WriteLine($"Error in row {context.RawRow}: {context.RawRecord}");};You can also use attributes for field validation:
public class Product{ [Name("ProductId")] public int Id { get; set; } [Required] public string Nam