问题
With CsvHelper, when I want a custom parser (for example, I want a MyBooleanConverter with the input string is "f" will be false, "t" will be "true"). But with every class I have to write mapper:
public sealed class MyClassMap : CsvClassMap<MyClass>
{
    public MyClassMap()
    {
        Map( m => m.Id ).Index( 0 ).TypeConverter<MyBooleanConverter>();
    }
}
Or
[CsvHelper.TypeConversion.TypeConverter( typeof( MyBooleanConverter) )]
public Boolean MyObjectProperty { get; set; }
How can I set MyBooleanConverter as default for every boolean field and every Class?
回答1:
The CsvHelper library exposes a static TypeConverterFactory. You can simply remove the default Boolean converter and add your custom converter to replace it.
TypeConverterFactory.RemoveConverter<bool>();
TypeConverterFactory.AddConverter<bool>(new MyBooleanConverter());
    回答2:
Just adding my code snippet to the following post to help understand the Type Converters built into CsvHelper. I needed to handle dates in the following format "yyyyMMdd" and it seemed to do the trick writing back and forth to CSV without the .net DateTime Parse error: "String was not recognized as a valid DateTime."
using (TextWriter writer = new StreamWriter(csvLocaitonAndName))
        {
            var csvUpdate = new CsvWriter(writer);
            csvUpdate.Configuration.TypeConverterCache.AddConverter<DateTime?>(new DateConverter("yyyyMMdd"));
            csvUpdate.Configuration.HasHeaderRecord = false;
            csvUpdate.WriteRecords(list);
        }
public class DateConverter : ITypeConverter
    {
        private readonly string _dateFormat;
        public DateConverter(string dateFormat)
        {
            _dateFormat = dateFormat;
        }
        public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
        {
            if (!string.IsNullOrEmpty(text))
            {
                DateTime dt;
                DateTime.TryParseExact(text, _dateFormat,
                                       CultureInfo.InvariantCulture,
                                       DateTimeStyles.None,
                                       out dt);
                if (IsValidSqlDateTime(dt))
                {
                    return dt;
                }
            }
            return null;
        }
        public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
        {
            return ObjectToDateString(value, _dateFormat);
        }
        public string ObjectToDateString(object o, string dateFormat)
        {
            if (o == null) return string.Empty;
            DateTime dt;
            if (DateTime.TryParse(o.ToString(), out dt))
                return dt.ToString(dateFormat);
            else
                return string.Empty; 
        }
        public bool IsValidSqlDateTime(DateTime? dateTime)
        {
            if (dateTime == null) return true;
            DateTime minValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MinValue.ToString());
            DateTime maxValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString());
            if (minValue > dateTime.Value || maxValue < dateTime.Value)
                return false;
            return true;
        }
    回答3:
It's also possible to have CsvHelper generate your ClassMap, at which point you can customize its handling for your members. I found this useful for getting things done in my little hobby project.
var csv = new CsvReader(streamReader, false);
var classMap = csv.Configuration.AutoMap<Row>(); // ClassMap creation
// My price data has dollar signs so those need to be stripped out before parsing to a decimal
classMap.Map(row => row.Price).ConvertUsing(row => decimal.Parse(row.GetField("Price").Replace("$", "")));
// CsvHelper doesn't support URIs so that requires help as well
classMap.Map(row => row.Source).ConvertUsing(row => new Uri(row.GetField("Source")));
var prices = csv.GetRecords<Row>();
// my DTO
class Row
{
    public decimal Price { get; set; }
    public string ManufacturerSku { get; set; }
    public string Manufacturer { get; set; }
    public Uri Source { get; set; }
    public DateTimeOffset Extraction_Time { get; set; }
}
    来源:https://stackoverflow.com/questions/42133413/csvhelper-set-default-custom-typeconverter