При использовании библиотеки. NET CsvHelper существует ли простой способ поместить поля базового класса на первое место? - PullRequest
0 голосов
/ 21 апреля 2020

Я сериализую ряд различных объектов POCO, которые все наследуются от общего абстрактного класса, например, AbstractBaseClass. При сериализации этого класса я использую метод WriteRecords<dynamic>, который принимает практически все и якобы использует отражение для записи свойств в CSV.

Проблема, с которой я столкнулся, заключается в том, что мне нужны поля базового класса прийти первым в файле. Похоже, что поведение CsvHelper по умолчанию ставит их последними.

Я вижу, что существует способ создания картографа для индексации полей, но это довольно сложно сделать для каждого из множества типов, наследуемых от AbstractBaseClass. Я хотел бы настроить это только один раз, и он будет работать для всего, что наследуется от указанного класса. Еще лучше было бы переключение, которое может позволить мне изменить способ поиска полей в дереве наследования CsvHelper.

1 Ответ

1 голос
/ 21 апреля 2020

Вы можете использовать метод generi c для создания ClassMap и установить индексы на свойствах базового класса как отрицательные, чтобы они предшествовали свойствам унаследованного класса.

public class Program
{
    public static void Main(string[] args)
    {        
        var records = new List<Foo> {
            new Foo{Id = 1, FirstName = "FirstName1", FooProperty = "Foo1", LastName = "LastName1"},
            new Foo{Id = 2, FirstName = "FirstName2", FooProperty = "Foo2", LastName = "LastName2"}
        };

        var config = GetFooBaseConfiguration(records);

        using (var csv = new CsvWriter(Console.Out, config))
        {
            csv.WriteRecords(records);
        }

        Console.ReadKey();
    }

    public static CsvConfiguration GetFooBaseConfiguration<T>(IEnumerable<T> records) where T : FooBase
    {
        var config = new CsvConfiguration(CultureInfo.InvariantCulture);

        var classMap = new DefaultClassMap<T>();

        classMap.AutoMap(CultureInfo.InvariantCulture);
        classMap.Map(m => m.FirstName).Index(-1,-2);
        classMap.Map(m => m.LastName).Index(-2,-3);

        config.RegisterClassMap(classMap);

        return config;
    }
}

public abstract class FooBase
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Foo : FooBase
{
    public int Id { get; set; }
    public string FooProperty { get; set; }
}
...