-
Notifications
You must be signed in to change notification settings - Fork 3
Custom Types
You can define custom types for representing columns in your CSV file. NetCsv taps into the TypeDescriptor/TypeConverter ecosystem to realize this.
.NET has a built-in facility to facilitate type conversion, through the TypeConverter class. NetCsv taps into this system when using schema-based csv reading and writing.
As an example, suppose you have a custom value type that represents a currency, formatted as a string value with the currency, a space and the amount in decimal format:
public struct Amount
{
public string Currency { get; set; }
public decimal Value { get; set; }
public static Amount Parse(string s, IFormatProvider provider)
{
var parts = s.Split(' ');
var currency = parts[0];
var decimalValue = decimal.Parse(parts[1], provider);
return new Amount { Currency = currency, Value = decimalValue } ;
}
public string ToString(IFormatProvider provider)
{
return $"{Currency} {Value.ToString(provider)}";
}
public override string ToString() => ToString(CultureInfo.CurrentCulture);
}Conversion of this type to and from a string can be implemented by providing a TypeConverter class similar to the following:
public class AmountConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
=> sourceType == typeof(string);
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
=> destinationType == typeof(Amount);
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string s) return Amount.Parse(s, culture);
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
object value, Type destinationType)
{
if (value is Amount a && destinationType == typeof(string)) return a.ToString(culture);
return base.ConvertTo(context, culture, value, destinationType);
}
}As you can see, the ConvertFrom method can create an Amount from a string, while ConvertTo will handle conversion from Amount to string. By applying the TypeConverterAttribute to the Amount struct, NetCsv will use this converter to convert a string it reads in the CSV file to the Amount type:
[TypeConverter(typeof(AmountConverter))]
public struct Amount
{
// etc...
}