Efficient CSV Parsing in C#: Best Practices with TextFieldParser Class

Nov 20, 2025 · Programming · 12 views · 7.8

Keywords: C# | CSV Parsing | TextFieldParser

Abstract: This article explores efficient methods for parsing CSV files in C#, focusing on the use of the Microsoft.VisualBasic.FileIO.TextFieldParser class. By comparing the limitations of traditional array splitting approaches, it details the advantages of TextFieldParser in field parsing, error handling, and performance optimization. Complete code examples demonstrate how to read CSV data, detect corrupted lines, and display results in DataGrids, alongside discussions of best practices and common issue resolutions in real-world applications.

Introduction

In data processing applications, CSV (Comma-Separated Values) files are widely used due to their simplicity and universality. However, manual parsing of CSV files often leads to complex and error-prone code, especially when dealing with special cases such as fields containing commas or newlines. Based on Q&A data and reference articles, this article systematically introduces how to use the TextFieldParser class in C# for efficient CSV parsing, avoiding reinventing the wheel and improving development efficiency.

Limitations of Traditional Methods

In initial implementations, developers commonly use StreamReader and the Split method to read and split CSV data line by line. For example, the following code attempts to parse each line and create transaction objects:

StreamReader sr = new StreamReader(FilePath);
importingData = new Account();
string line;
string[] row = new string [5];
while ((line = sr.ReadLine()) != null)
{
    row = line.Split(',');
    importingData.Add(new Transaction
    {
        Date = DateTime.Parse(row[0]),
        Reference = row[1],
        Description = row[2],
        Amount = decimal.Parse(row[3]),
        Category = (Category)Enum.Parse(typeof(Category), row[4])
    });
}

This approach has several issues: first, it assumes each line has exactly five fields, ignoring potential variations in CSV row lengths; second, the Split method cannot handle embedded commas in fields, such as "Smith, John", which causes incorrect field splitting; moreover, array operations are cumbersome and lack built-in error handling, making it difficult to detect corrupted lines (e.g., insufficient field counts). The reference article emphasizes the importance of defining data classes (e.g., Person) to store parsed results but does not address core parsing problems.

Advantages of the TextFieldParser Class

To address these issues, the .NET Base Class Library (BCL) provides the Microsoft.VisualBasic.FileIO.TextFieldParser class. Although the namespace includes "VisualBasic", this class is fully compatible with C# and generates intermediate language (IL) at the底层, ensuring cross-language consistency. Its core advantages include:

Implementing CSV File Parsing

The following code demonstrates how to use TextFieldParser to read a CSV file, bind data to a DataGrid, and separate corrupted lines into another grid. First, add a reference to the Microsoft.VisualBasic assembly, then use the parser in code:

using Microsoft.VisualBasic.FileIO;
using System.Data;

// Define data model class
public class Transaction
{
    public DateTime Date { get; set; }
    public string Reference { get; set; }
    public string Description { get; set; }
    public decimal Amount { get; set; }
    public Category Category { get; set; }
}

// Main parsing logic
DataTable validDataTable = new DataTable();
DataTable corruptedDataTable = new DataTable();

// Initialize DataTable structure (example)
validDataTable.Columns.Add("Date", typeof(DateTime));
validDataTable.Columns.Add("Reference", typeof(string));
validDataTable.Columns.Add("Description", typeof(string));
validDataTable.Columns.Add("Amount", typeof(decimal));
validDataTable.Columns.Add("Category", typeof(Category));
corruptedDataTable.Columns.Add("CorruptedLine", typeof(string));

using (TextFieldParser parser = new TextFieldParser(@"c:\temp\test.csv"))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    
    while (!parser.EndOfData)
    {
        try
        {
            string[] fields = parser.ReadFields();
            if (fields.Length == 5) // Assuming standard rows have 5 fields
            {
                // Parse valid data and add to DataTable
                validDataTable.Rows.Add(
                    DateTime.Parse(fields[0]),
                    fields[1],
                    fields[2],
                    decimal.Parse(fields[3]),
                    Enum.Parse(typeof(Category), fields[4])
                );
            }
            else
            {
                // Insufficient fields, treat as corrupted line
                corruptedDataTable.Rows.Add(string.Join(",", fields));
            }
        }
        catch (Exception ex)
        {
            // Handle parsing errors (e.g., invalid formats)
            corruptedDataTable.Rows.Add($"Error: {ex.Message} - Line: {parser.LineNumber}");
        }
    }
}

// Bind DataGrid (assuming dataGridValid and dataGridCorrupted are UI controls)
dataGridValid.ItemsSource = validDataTable.DefaultView;
dataGridCorrupted.ItemsSource = corruptedDataTable.DefaultView;

In this implementation, TextFieldParser reads the file line by line, using the ReadFields method to return an array of fields. By checking the field count (e.g., standard rows should have five), we can identify corrupted lines (e.g., those with fewer than five fields). The try-catch block captures parsing exceptions (e.g., invalid date or number formats), ensuring application stability. The reference article mentions using File.ReadAllLines and Split, but this method lacks such advanced features.

Advanced Features and Best Practices

TextFieldParser offers additional features to enhance parsing:

Best practices include: always using using statements for resource management; handling exceptions within loops to avoid overall parsing failure; predefining data models (e.g., Transaction class) to improve code readability and type safety. For large datasets, consider asynchronous reading to prevent UI blocking.

Conclusion

Using the TextFieldParser class for CSV parsing is significantly superior to manual array operations. It simplifies code structure, provides robust error handling, and is compatible with C# environments. Developers should prioritize leveraging existing tools in the .NET BCL to reduce custom parsing logic, thereby enhancing application maintainability and performance. The examples in this article demonstrate how to integrate parsing, data binding, and error detection, offering a practical guide for real-world projects.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.