I am trying to serialize / deserialize a collection of interfaces that are mostly not supported. I found a question on SO that claims to provide serializable shell properties for these interface-dependent properties. So what I have:
public class Serialize { public Serialize() { this.SCollection = new SerializableInterfacesCollection<ObservableCollection<A>>(new ObservableCollection<A>()); } [XmlIgnore()] public ObservableCollection<A> Collection { get { return this.SCollection.Value; } set { SCollection.Value = value; } } public SerializableInterfacesCollection<ObservableCollection<A>> SCollection { get; set; } } public interface A { string Str { get; set; } int Int { get; set; } // bad properties... very bad: BB { get; set; } ObservableCollection<B> Collection {get;set;} } public interface B { string Label { get; set; } string Value { get; set; } } public class AImpl: A { public AImpl() { SB = new SerializableInterface<B>(); SCollection = new SerializableInterfacesCollection<ObservableCollection<B>>(new ObservableCollection<B>()); } [XmlAttribute()] public string Type = typeof(AImpl).FullName; public string Str {get;set;} public int Int {get;set;} [XmlIgnore()] public BB { get { return SB.Value; } set { SB.Value = value; } } public SerializableInterface<B> SB; [XmlIgnore()] public ObservableCollection<B> Collection { get { return SCollection.Value; } set { SCollection.Value = value; } } public SerializableInterfacesCollection<ObservableCollection<B>> SCollection { get; set; } } public class BImpl01: B { [XmlAttribute()] public string Type = typeof(BImpl01).FullName; public string Label {get;set;} public string Value {get;set;} } public class BImpl02: B { [XmlAttribute()] public string Type = typeof(BImpl02).FullName; public string Label {get;set;} public string Value {get;set;} }
Everything works fine if interface A does not include "bad properties" (and, of course, they do not appear in the AImpl class). If he does, than the collection item does not deserialize and stops after deserializing the first property of interface B.
Here are the wrappers:
public class SerializableInterface<T>: IXmlSerializable { public SerializableInterface(T value) { Value = value; } public SerializableInterface() { } public T Value { get; set; } public const string TypeAttr = "Type"; public const string NullAttrValue = "null"; #region IXmlSerializable Members public System.Xml.Schema.XmlSchema GetSchema() { return null; } public virtual void ReadXml(System.Xml.XmlReader reader) { if (!reader.HasAttributes) throw new FormatException("expected a type attribute!"); string type = reader.GetAttribute(TypeAttr); reader.Read();
and here is the method generating the data for the tests:
private Serialize makeA() { Serialize result = new Serialize(); for (int i = 0; i < 10; ++i) { A a = new AImpl() { Str = "str " + i, Int = i, B = makeB(i) }; for (int j = 0; j < 10; ++j) { a.Collection.Add(makeB(j)); } result.Collection.Add(a); } return result; } B makeB(int i) { if (i % 2 == 0) { return new BImpl01(){Label= "Blabel " + i, Value="value b"+i}; } else { return new BImpl02(){Label= "B2label " + i, Value="value b2"+i}; } }
c # deserialization xml-serialization
SOReader Sep 28 2018-11-11T00: 00Z
source share