使用 CSVHelper 反序列化 CSV 时使用特定函数创建对象的新实例

Using specific function to create new instance of object when deserializing CSV using CSVHelper

我正在使用 JoshClose's CsvHelper library 将数据序列化和反序列化为 CSV。

我面临以下问题:在反序列化我的数据时,我想使用一个特定的函数来创建一个正在反序列化的 class 的新实例。

我看到了 I can use a specific constructor as indicated here,但在我的例子中,我想使用一个 不是 构造函数的函数(但仍然是 returns 一个新的我的 class 的实例)。这甚至可能吗?

另一种解决方案是允许 CSVHelper "override" 我的 class 的现有实例的值。这可能吗?

这是我目前的代码:

private MyClass[] DeserializeFromCSV( string csv )
{
    MyClass[] output = null;
    using ( System.IO.TextReader textReader = new System.IO.StringReader( csv ) )
    using ( CsvHelper.CsvReader csvReader = new CsvHelper.CsvReader( textReader ) )
    {
        // Here, I would like to provide the function to call
        // in order to instantiate a new instance of the class

        // The function I want to call does not return a `ConstructorInfo`
        // as needed by the property here
        //csvReader.Configuration.GetConstructor = type =>
        //{
        //    return null;
        //};


        // CSVClassMap is a getter to get a ClassMap
        csvReader.Configuration.RegisterClassMap( CSVClassMap );
        csvReader.Read();
        output = csvReader.GetRecords<T>().ToArray();
    }

    return output;
}

您可以使用 CsvHelper.ObjectResolver 来执行此操作。

void Main()
{
    var s = new StringBuilder();
    s.Append("Id,Name\r\n");
    s.Append("1,one\r\n");
    s.Append("2,two\r\n");
    using (var reader = new StringReader(s.ToString()))
    using (var csv = new CsvReader(reader))
    {
        CsvHelper.ObjectResolver.Current = new ObjectResolver(CanResolve, Resolve);
        csv.Configuration.RegisterClassMap<TestMap>();
        csv.GetRecords<Test>().ToList().Dump();
    }
}

public bool CanResolve(Type type)
{   
    return type == typeof(Test);
}

public object Resolve(Type type, object[] constructorArgs)
{   
    // Get a dependency from somewhere.
    var someDependency = new object();

    return new Test(someDependency);
}

public class Test
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Test(object someDependency) { }
}

public class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
    }
}