Я люблю простые костыли.
Когда требуется сериализовать некоторые поля в какой-то текстовый формат,
бывает удобно использовать промежуточное представление данных вида:
// Name/Value item public class NVItem { public string? Name; public object? Value; public IEnumerable<NVItem>? SubItems; public NVItem(string? name, object? value) { Name = name; if (value==null) return; SubItems = value as IEnumerable<NVItem>; if (SubItems != null) return; // Упс! Value = value as string; if (Value != null) return; var num = value as IEnumerable; if (num==null) { Value = value; } else { SubItems = num.Cast<object>().Select(t => new NVItem(null, t)); } } }
Которое затем конвертируется в XML, JSON или что-нибудь ещё.
Например, так:
IEnumerable<NVItem> GetTypeInfo(Type type) { return new NVItem[] { new NVItem("Name", type.Name), new NVItem("FullName", type.FullName), new NVItem("CustomAttributes", type.CustomAttributes), }; }
Это можно реализовать и по-изящнее, но костыль улучшать - только портить.
Если требуется преобразовать данное представление в текст, воспользуемся следующими методами:
public static class NVItemExtensions { public static IEnumerable<string> ToStrings(this NVItem item) { yield return item.Name+'='+item.Value?.ToString(); if (item.SubItems!=null) { foreach (string s in item.SubItems.SelectMany(t => t.ToStrings())) { yield return " "+s; } } } public static string AsString(this IEnumerable<NVItem> items) { return string.Join('\n', items.SelectMany(t => t.ToStrings())); } } string info = GetTypeInfo(typeof(string)).AsString();
Получаем:
Name=String FullName=System.String CustomAttributes= =[System.SerializableAttribute()] =[System.Runtime.CompilerServices.NullableContextAttribute((Byte)1)] =[System.Runtime.CompilerServices.NullableAttribute((Byte)0)] =[System.Reflection.DefaultMemberAttribute("Chars")] =[System.Runtime.Versioning.NonVersionableAttribute()] ...
Теперь заметим, что если:
- наши Name не начинаются с пробела и не содержат символов '=' и '\n',
- наши Value не содержат символов '\n',
- и нам не надо различать пустые строки и null,
то получаемый текст можно преобразовать обратно, за тем исключением, что Value теперь строки.
У меня не было такой надобности, но если сам пишешь - сам читаешь, то это вполне рабочий вариант сериализации. А вот сохранять настройки в подобный файл с намерением редактировать вручную, это не лучший выбор.
Форматы конфигов, как и все другие решения для всего, придумывают злые гении с подобающими им амбициями:
Habr: Tree — убийца JSON, XML, YAML и иже с ними
Habr: Почему JSON и YAML мешают вам писать нормальные конфиги (и чем их заменить)
Habr: JSON? JSONB? BSON? CBOR? MsgPack? А, VaryPackǃ
