Немного контекста: я реализую сериализацию в довольно крупномасштабном проекте, который сохраняет данные в файл или несколько файлов.Хотя я не одинок в проекте, я единственный, кто имеет некоторый опыт в сериализации, хотя, очевидно, этого недостаточно, чтобы понять это самостоятельно.
Цель состоит в том, чтобы создать библиотеку классов, чтобы мы моглиможет реализовать MVVM и позволяет легко разрабатывать с учетом кросс-платформенности.Это означает, что все незащищенные классы должны быть внутренними.Кроме того, некоторым данным предоставляются защищенные или закрытые сеттеры, чтобы избежать мутации там, где этого не должно происходить, даже в библиотеке классов.Еще более усложняет вопрос то, что некоторые классы имеют базовые классы с конструкторами не по умолчанию, которые инициализируют поля, которые используются и не могут иметь значение null или значение по умолчанию (для типов, не допускающих значения NULL).Обычно они инициализируют поля только для чтения.
Мне нужно иметь возможность выборочно сериализовать данные для любого уровня доступности, а также вызвать любой базовый конструктор и предоставить ему правильные аргументы.
У меня естьпробовал: BinaryFormatter , DataContractSerializer и XmlSerializer
Мне больше всего повезло с DataContractSerializer, так как он позволяет свойства с непубличными get /настроен на сериализацию хорошо и является отказом вместо отказа, как BinaryFormatter.Проблема в том, что каждый из них обеспечивает автоматический метод сериализации - без вызова конструктора.Мне известны атрибуты OnSerializing / OnDeserializing / OnDeserialized / OnSerialized.к сожалению, они не могут устанавливать свойства только для чтения или вызывать базовый конструктор.
Ранее я также реализовывал версии своих классов "Serializer" с пустыми конструкторами, которые затем я могу передать в конструктор реального класса, и пока он работает, это утомительно и требует много переписывания идентичного кода только для принудительного конструктора, не говоря уже о дополнительном использовании памяти.
Я также пытался использовать ISerializable , что позволяет мне форсироватьконструктор, который позволяет мне вызывать базовый конструктор и предоставлять необходимые значения, если это необходимо.однако он не использует сериализацию по умолчанию, которая делает атрибуты Serialize / DataMember действительно полезными.
Я думал, что у меня есть умный обходной путь, используя Reflection и пользовательский атрибут:
protected SerializeClassDemo(SerializationInfo info, StreamingContext context)
{
List<PropertyInfo> propertySaveables = saveableProperties();
foreach (PropertyInfo saveable in propertySaveables)
{
saveable.SetValue(this, info.GetValue(saveable.Name, saveable.PropertyType));
}
List<FieldInfo> fieldSaveables = saveableFields();
foreach (FieldInfo saveable in fieldSaveables)
{
saveable.SetValue(this, info.GetValue(saveable.Name, saveable.FieldType));
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
List<PropertyInfo> propertySaveables = saveableProperties();
foreach (PropertyInfo saveable in propertySaveables)
{
info.AddValue(saveable.Name, saveable.GetValue(this), saveable.PropertyType);
}
List<FieldInfo> fieldSaveables = saveableFields();
foreach (FieldInfo saveable in fieldSaveables)
{
info.AddValue(saveable.Name, saveable.GetValue(this), saveable.FieldType);
}
}
private List<PropertyInfo> saveableProperties()
{
List<PropertyInfo> saveables = new List<PropertyInfo>();
PropertyInfo[] props = typeof(SerializeClassDemo).GetProperties();
foreach (PropertyInfo prop in props)
{
SaveAttribute attrs = prop.GetCustomAttribute<SaveAttribute>();
if (attrs != null)
{
saveables.Add(prop);
}
}
return saveables;
}
private List<FieldInfo> saveableFields()
{
List<FieldInfo> saveables = new List<FieldInfo>();
FieldInfo[] fields = typeof(SerializeClassDemo).GetFields();
foreach (FieldInfo field in fields)
{
SaveAttribute attrs = field.GetCustomAttribute<SaveAttribute>();
if (attrs != null)
{
saveables.Add(field);
}
}
return saveables;
}
, который автоматически сериализует и десериализует данные, как это делает стандартная XmlSerialization, но способ, которым я использовал только отражениеработает с публичными участниками.
В этот момент я пришел к выводу, что, хотя в конечном итоге я мог бы наткнуться на достаточно страниц документации, чтобы найти идеальное решение, я, вероятно, сэкономил бы время и усилия, просто спросив - есть ли относительно простой способсериализовать / десериализовать данные, которые работают с внутренними / защищенными данными и позволяют мне удовлетворить базовый конструктор, требующий аргументов?
Редактировать: проект будет бесплатным, и лицензия напроект GPL-3, который удовлетворяет требованию креативного общего использования переполнения стека для использования любого предоставленного кода.Я не буду зарабатывать деньги на оказанной помощи.веселит.