如何将EnumConverter与CsvHelper一起使用

我正在使用CsvHelper将类序列化为csv文件 – 直到这里一切正常。

现在我正在尝试找到一种方法将类的枚举属性转换为csv中的int值,因此我可以稍后使用CSV进行批量插入。

我在CsvHelper中发现了EnumConverter类,但我无法弄清楚如何正确使用它,因为我的所有尝试都失败了。

这是我的映射类代码

public sealed class MyMapping : CsvClassMap { public MyMapping() { EnumConverter enumConverter = new EnumConverter(typeof(CalendarExceptionEntityType)); Map(m => m.ExceptionEntityType).Index(0).Name("EXCEPTION_ENTITY_TYPE").TypeConverter(enumConverter); Map(m => m.ExceptionEntityIdentifier).Index(1).Name("EXCEPTION_ENTITY_IDENTIFIER"); Map(m => m.OptionType).Index(2).Name("OPTION_TYPE"); Map(m => m.StartDatetime).Index(3).Name("EXCEPTION_START_DATETIME"); Map(m => m.EndDatetime).Index(4).Name("EXCEPTION_END_DATETIME"); Map(m => m.DataSourceType).Index(5).Name("DATA_SOURCE_TYPE"); Map(m => m.Description).Index(6).Name("DESCRIPTION"); } } 

和写作部分

 using (StreamWriter file = new StreamWriter(filePath, false, Encoding.UTF8)) { CsvWriter writer = new CsvWriter(file); MyMapping mapping = new MyMapping(); writer.Configuration.RegisterClassMap(mapping); writer.WriteRecords(calendarExceptionList); } 

映射的其余部分(索引和命名)正在工作 ,它只是EnumConverter不做任何更改。

我没有在网上找到任何例子。

谢谢!

这是我做的解决方案:

 public class CalendarExceptionEnumConverter : DefaultTypeConverter where T : struct { public override string ConvertToString(TypeConverterOptions options, object value) { T result; if(Enum.TryParse(value.ToString(),out result)) { return (Convert.ToInt32(result)).ToString(); } throw new InvalidCastException(String.Format("Invalid value to EnumConverter. Type: {0} Value: {1}",typeof(T),value)); } } 

并将其用作以下内容:

 Map(m => m.ExceptionEntityType).TypeConverter>(); 

我使用了Yarimi的解决方案,但发现它无法从.csv中读取枚举值(可以写好)

我的解决方案是使类从EnumTypeConverter扩展,而不是DefaultTypeConverter。

这是完整的代码

  public class OurEnumConverter : CsvHelper.TypeConversion.EnumConverter where T : struct { public OurEnumConverter(): base(typeof(T)) { } public override string ConvertToString(CsvHelper.TypeConversion.TypeConverterOptions options, object value) { T result; if (Enum.TryParse(value.ToString(), out result)) { return (Convert.ToInt32(result)).ToString(); } return base.ConvertToString(options, value); //throw new InvalidCastException(String.Format("Invalid value to EnumConverter. Type: {0} Value: {1}", typeof (T), value)); } public override object ConvertFromString(TypeConverterOptions options, string text) { int parsedValue; //System.Diagnostics.Debug.WriteLine($"{typeof(T).Name} = {text}"); if (Int32.TryParse(text, out parsedValue)) { return (T)(object)parsedValue; } return base.ConvertFromString(options, text); //throw new InvalidCastException(String.Format("Invalid value to EnumConverter. Type: {0} Value: {1}", typeof(T), text)); } } 

以下是它的使用方法

 public class TickTradeClassMap : CsvHelper.Configuration.CsvClassMap { public TickTradeClassMap() { Map(m => m.price); Map(m => m.size); Map(m => m.exchange).TypeConverter>(); Map(m => m.condition1).TypeConverter>(); } } 

在您的TradingCalendarException类中添加一个int属性,该类可以来回转换为您的自定义枚举CalendarExceptionEntityType ,如:

 public int ExceptionEntityTypeInt { get { return (int)ExceptionEntityType; } set { ExceptionEntityType = (CalendarExceptionEntityType)value; } } 

使用Map(m => m.ExceptionEntityTypeInt).Index(0).Name("EXCEPTION_ENTITY_TYPE_INT")代替你的枚举转换器Map(m => m.ExceptionEntityType).Index(0).Name("EXCEPTION_ENTITY_TYPE").TypeConverter(new MyMapping())

这就是我为最新版本的CSV Helper 7.1.1所做的事情:

 public class AggregateEnumConverter : EnumConverter where T : struct { public AggregateEnumConverter() : base(typeof(T)) { } public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData) { if(!Enum.TryParse(text, out AggregateType aggregateType)) { // This is just to make the user life simpler... if(text == "24HAVG") { return AggregateType._24HAVG; } // If an invalid value is found in the CSV for the Aggregate column, throw an exception... throw new InvalidCastException($"Invalid value to EnumConverter. Type: {typeof(T)} Value: {text}"); } return aggregateType; } } 

注意:上面的代码使用了C#7新的内联输出变量。
更多信息: 我应该如何将字符串转换为C#中的枚举?

这是您使用自定义EnumConverter

 ///  /// Maps Tag class properties to the CSV columns' names ///  public sealed class TagMap : ClassMap { public TagMap(ILogger logger) { Map(tag => tag.Aggregate).Name("aggregate").TypeConverter>(); } }