Search code examples
c#csvhelper

Using external classes/variables with CustomTypeConverter


I need to convert a double field into a custom string output depending on a mapped class' parameter. This is most easily shown with code.

public enum Type {
    Mod,
    NonMod
}

public class Document {
    public double Value { get; set; }
    public Type DocType { get; set; }
}

Now attempting to convert the Value field...
public class DocumentMap : ClassMap<Document>
{
    public DocumentMap
    {
        Map(m => m.Value).Index(0).Name("Value").TypeConverter<CustomDoubleConverter>()
        Map(m => m.Type).Index(1).Name("Type");
    }

    private class CustomDoubleConverter : DefaultTypeConverter
    {
        public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
        {
            return text == "ModVal" ? null : double.Parse(text);
        }
        public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
        {
            return (double)value == 0 /* && Document.Type == Type.Mod*/ ? "ModVal" : value.ToString();
        }
    }
}

I would need the Document type within CustomDoubleConverter to write "ModVal" only for Mod type documents. The only issue is converting the value to a string as converting back would mean it was properly delineated initially. I would need to know the document types for each of the documents, so I don't believe a parameter could be passed into the DocumentMap instantiation as it is only instantiated once.


Solution

  • I'm not quite sure I understand all of your logic, but I think Convert could work for you in the ClassMap.

    public class DocumentMap : ClassMap<Document>
    {
        public DocumentMap()
        {
            Map(m => m.Value).Name("Value")
            .Convert(args =>
            {
                var value = args.Row.GetField<string>(0);
                
                return value == "ModVal" ? 0 : double.Parse(value);
    
            }).Convert(args =>
            {
                return args.Value.Value == 0 && args.Value.DocType == Type.Mod ? "ModVal" : args.Value.Value.ToString();
            });
            Map(m => m.DocType).Index(1).Name("Type");
        }
    }