using CsvHelper.TypeConversion;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using System.Globalization;
public static void Main()
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("Name", typeof(string)));
dataTable.Columns.Add(new DataColumn("Credits", typeof(int)) { DefaultValue = 0 });
dataTable.Columns.Add(new DataColumn("Notes", typeof(string)));
dataTable.Columns.Add(new DataColumn("LastLogin", typeof(DateTime)));
dataTable.Columns.Add(new DataColumn("Balance", typeof(decimal)) { DefaultValue = 0 });
StringBuilder sbInput = new StringBuilder();
sbInput.AppendLine("Name;Credits;Notes;LastLogin;Balance");
sbInput.AppendLine("Michael;;Good guy;2023-03-28;736.26");
sbInput.AppendLine("John;3;Bad guy;2023-04-01;-49.25");
CsvConfiguration csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
NewLine = Environment.NewLine,
using (var csvReader = new CsvReader(new StringReader(sbInput.ToString()), csvConfiguration))
csvReader.Context.TypeConverterCache.RemoveConverter<int>();
csvReader.Context.TypeConverterCache.AddConverter<int>(new DefaultNumericConverter<int>());
csvReader.Context.TypeConverterCache.RemoveConverter<decimal>();
csvReader.Context.TypeConverterCache.AddConverter<decimal>(new DefaultNumericConverter<decimal>());
var row = dataTable.NewRow();
foreach (DataColumn column in dataTable.Columns)
row[column.ColumnName] = csvReader.GetField(column.DataType, column.ColumnName);
Console.WriteLine(String.Join(",", dataTable.Columns.Cast<DataColumn>().Select(x => x.ColumnName)));
foreach(DataRow row in dataTable.Rows)
Console.WriteLine(String.Join(",", row.ItemArray));
public class DefaultNumericConverter<T> : DefaultTypeConverter
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
if (String.IsNullOrWhiteSpace(text))
if (int.TryParse(text, memberMapData.TypeConverterOptions.NumberStyles ?? NumberStyles.Integer, memberMapData.TypeConverterOptions.CultureInfo, out var i))
else if (type == typeof(decimal))
if (decimal.TryParse(text, memberMapData.TypeConverterOptions.NumberStyles ?? NumberStyles.Currency, memberMapData.TypeConverterOptions.CultureInfo, out var m))
return base.ConvertFromString(text, row, memberMapData);