Я пытаюсь реализовать абстракцию для базовой сериализации в C # за пользовательским атрибутом, который называется GenericSerializable
.По сути, я хочу, чтобы этот атрибут при применении к общему свойству указывал некоторому сериализатору (будь то XML, JSON, Protobuf и т. Д.), Что это свойство должно быть сериализовано, а если оно отсутствует, его не следует сериализовать.В настоящее время я могу получить информацию о том, имеет ли конкретное свойство этот атрибут или нет, но я изо всех сил пытаюсь реализовать сериализатор XML.Вот моя тестовая структура наследования:
public abstract class SerializableObjectBase
{
protected int _typeIndicator;
[GenericSerializable]
public int TypeIndicator
{
get
{
return _typeIndicator;
}
}
public SerializableObjectBase()
{
_typeIndicator = 0;
}
}
public class SerializableObjectChildOne : SerializableObjectBase
{
private int _test;
public int Test
{
get
{
return _test;
}
set
{
_test = value;
}
}
public SerializableObjectChildOne() : base()
{
_test = 1234;
_typeIndicator = 1;
}
}
public class SerializableObjectChildTwo : SerializableObjectChildOne
{
private List<int> _list;
public List<int> List
{
get
{
return _list;
}
}
public SerializableObjectChildTwo() : base()
{
_list = new List<int>();
_typeIndicator = 2;
}
}
Я хочу, чтобы XML для этого примера выглядел следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<SerializableObjectChildTwo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<TypeIndicator>2</TypeIndicator>
</SerializableObjectChildTwo>
Но вместо этого он выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<SerializableObjectChildTwo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Test>1234</Test>
</SerializableObjectChildTwo>
Вот код сериализации:
using (FileStream fs = new FileStream(".\\output.xml", FileMode.Create))
{
// object to serialize
SerializableObjectChildTwo s = new SerializableObjectChildTwo();
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
// check whether each property has the custom attribute
foreach (PropertyInfo property in typeof(SerializableObjectChildTwo).GetProperties())
{
XmlAttributes attrbs = new XmlAttributes();
// if it has the attribute, tell the overrides to serialize this property
if (property.CustomAttributes.Any((attr) => attr.AttributeType.Equals(typeof(GenericSerializable))))
{
Console.WriteLine("Adding " + property.Name + "");
attrbs.XmlElements.Add(new XmlElementAttribute(property.Name));
}
else
{
// otherwise, ignore the property
Console.WriteLine("Ignoring " + property.Name + "");
attrbs.XmlIgnore = true;
}
// add this property to the list of overrides
overrides.Add(typeof(SerializableObjectChildTwo), property.Name, attrbs);
}
// create the serializer
XmlSerializer xml = new XmlSerializer(typeof(SerializableObjectChildTwo), overrides);
// serialize it
using (TextWriter tw = new StreamWriter(fs))
{
xml.Serialize(tw, s);
}
}
Интересно, что если я добавлю атрибут GenericSerializable
к свойству List
в SerializableObjectChildTwo
, он будет работать так, как ожидается.Проблема в том, что по какой-то причине Test
сериализуется, несмотря на то, что я добавил attrbs.XmlIgnore = true
, а TypeIndicator
не сериализуется, несмотря на то, что я добавил его явно к XmlAttributeOverrides
.
Я неправильно использую переопределения?Мне не нужны какие-либо причудливые схемы XML или что-либо еще, я просто хочу, чтобы публичные свойства сериализировались / не сериализировались на основе наличия или отсутствия моего пользовательского свойства.
Заранее спасибо.