using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using CsvHelper.Expressions;
using CsvHelper.TypeConversion;
public abstract class MyDecimalConverter : DefaultTypeConverter
protected virtual string getFormat() => "";
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
return (d == 0) ? string.Empty : string.Format(getFormat(), d);
return base.ConvertToString(value, row, memberMapData);
public class DollarsConverter : MyDecimalConverter
protected override string getFormat() => "{0:0.00}";
public class HoursConverter : MyDecimalConverter
protected override string getFormat() => "{0:0.000}";
public class PayRateConverter : MyDecimalConverter
protected override string getFormat() => "{0:0.0000}";
public int EmployeeID { get; set; }
public decimal RegularPay { get; set; }
public decimal RegularHours { get; set; }
public decimal RegularRate { get; set; }
public decimal OvertimePay { get; set; }
public decimal OvertimeHours { get; set; }
public decimal OvertimeRate { get; set; }
public static void Test()
var record = new PayrollRecord
var sb = new StringBuilder();
using (var textWriter = new StringWriter(sb))
using (var writer = new CsvWriter( textWriter ))
var classMap = new DefaultClassMap<PayrollRecord>();
classMap.Map(m => m.RegularPay).TypeConverter<DollarsConverter>();
classMap.Map(m => m.RegularHours).TypeConverter<HoursConverter>();
classMap.Map(m => m.RegularRate).TypeConverter<PayRateConverter>();
classMap.Map(m => m.OvertimePay).TypeConverter<DollarsConverter>();
classMap.Map(m => m.OvertimeHours).TypeConverter<HoursConverter>();
classMap.Map(m => m.OvertimeRate).TypeConverter<PayRateConverter>();
writer.Configuration.RegisterClassMap(classMap);
writer.WriteHeader<PayrollRecord>();
writer.WriteRecord(record);
var expected = "EmployeeID,RegularPay,RegularHours,RegularRate,OvertimePay,OvertimeHours,OvertimeRate\r\n12,101.01,40.000,12.0000,202.02,1.100,24.0000";
Assert.IsTrue(csv == expected);
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("CsvHelper: " + typeof(CsvSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];