使用CsvHelper Reference<>时,已注册ClassMap实例未被调用的问题
CsvHelper中已注册带参ClassMap仍触发无参构造的问题
问题场景
定义的ClassMap代码如下:
internal sealed class MyOuterMap : ClassMap<MyOuterClass> { public MyOuterMap() { References<MyInnerMap>(x => x.MyInnerClassProperty); } } internal sealed class MyInnerMap : ClassMap<MyInnerClass> { public MyInnerMap(string p1, int p2) { } }
客户端代码:
using var csvReader = new CsvReader(streamReader, config); csvReader.Context.RegisterClassMap(new MyInnerMap("hello", 42)); csvReader.Context.RegisterClassMap<MyOuterMap>();
运行时抛出错误:
System.MissingMethodException: 'Constructor 'InnerMap()' was not found.'
疑问:明明已经注册了带参的MyInnerMap实例,为什么CsvHelper还是尝试实例化无参的MyInnerMap?
原因及解决方案
原因
在MyOuterMap构造函数中使用References<MyInnerMap>(x => x.MyInnerClassProperty)泛型方法时,CsvHelper会基于传入的类型MyInnerMap直接尝试创建新实例,不会去上下文查找已注册的同类型实例。泛型References方法的设计逻辑是通过类型初始化映射,而非复用已注册实例。
解决方案
有两种可行处理方式:
给
MyInnerMap添加无参构造函数
如果业务允许,可为MyInnerMap补充无参构造(即使是私有/内部构造,CsvHelper可通过反射访问),或者将参数依赖转移到其他逻辑中处理。在
MyOuterMap中直接引用已注册的MyInnerMap实例
修改MyOuterMap的构造,让它接收预先创建的MyInnerMap实例,使用非泛型References方法关联:internal sealed class MyOuterMap : ClassMap<MyOuterClass> { public MyOuterMap(MyInnerMap innerMap) { References(innerMap, x => x.MyInnerClassProperty); } }客户端调整注册顺序,先创建并注册
MyInnerMap,再传入给MyOuterMap:using var csvReader = new CsvReader(streamReader, config); var innerMap = new MyInnerMap("hello", 42); csvReader.Context.RegisterClassMap(innerMap); csvReader.Context.RegisterClassMap(new MyOuterMap(innerMap));这种方式会让
MyOuterMap直接使用预先配置好的带参MyInnerMap实例,避免CsvHelper尝试初始化新的无参实例。
内容的提问来源于stack exchange,提问作者g.pickardou
相关产品推荐
相关产品推荐

