К сожалению, я бы сказал, что так и должно быть. На выходе получается не файл XML, а файл CSV. И файл CSV имеет только один заголовок (если он есть; не все файлы CSV имеют заголовок).
Парсер не может определить класс по данным в строке.
Пример стандартных данных CSV 1 (имена):
ID,GivenName,FamilyName
1,John,A
2,Mike,B
Стандартные данные CSV, пример 2 ("годовщины"):
Date,Anniversary
1.1.,New year
При сохранении в файл CSV у вас не может быть двух «строк заголовка»; как синтаксический анализатор должен знать, в какой дочерний класс декодировать вывод? Имена или юбилеи? Почему первая строка "имя", а вторая "годовщина"? Почему нельзя по-другому?
Этот подход не является хорошим. По крайней мере, не для файла CSV. Всегда должна быть таблица с точным количеством столбцов для каждой строки. Когда количество данных всегда точное, вы можете использовать конвертеры из вашего класса в универсальный класс и из универсального класса в определенные классы данных (для парсера).
Пример нестандартных данных: (имена и годовщины; без строки заголовка):
1,John,A
1.1.,New year
2,Mike,B
Попробуйте спросить себя, как парсер должен обрабатывать этот файл? Да, данные хранятся "в формате CSV", но я не думаю, что эти данные верны. Это не так, как должно быть.
Я знаю, что есть ситуации, когда вам нужно использовать этот подход (форматированные данные, первый элемент указывает тип, все остальные значения в строке являются данными для данного типа). Но для этого использования вам нужно использовать другой подход к хранению и анализу данных.
Пример другого подхода:
public abstract class AbstractModel : ObservableObject
{
// no property
protected string Prefix(object data)
{
if (ReferenceEquals(data, null))
return string.Empty;
string result = data.ToString();
if (data.Contains(",") || data.Contains("\""))
return $"\"{data}\"";
return data;
}
}
public class RealModel : AbstractModel
{
public string PropertyA {get; set;}
public string PropertyB {get; set;}
public override string ToString()
{
return $"{Prefix(PropertyA)},{Prefix(PropertyB)}";
}
}
И сохранить с помощью:
using (StreamWriter file = new StreamWriter("path"))
{
foreach (AbstractModel instance in allInstances)
file.WriteLine(instance);
}
05.01.2016