Save objects with derived classes to disc
-
I have tested XmlSerializer but even if it works with derived classes I wonder if there isn´t a better way to save objects from derived classes. What I want to save is a List of derived objects.
What do you call "better"? You could serialize it in binary, but than you're no longer able to edit your data with a text-editor. OTOH, binary is smaller. Does that count as "better"? Nah, the "better" way would be to use a database. A relational one. With a normalized dataset. Up to BCNF.
Bastard Programmer from Hell :suss:
-
What do you call "better"? You could serialize it in binary, but than you're no longer able to edit your data with a text-editor. OTOH, binary is smaller. Does that count as "better"? Nah, the "better" way would be to use a database. A relational one. With a normalized dataset. Up to BCNF.
Bastard Programmer from Hell :suss:
-
Well, now I have to add an XmlInclude attribute to the Book parent class for each such sub-class. But as I understand it, the base-class shouldn´t have to know about the derived classes in OOP. As I remember in Java, you didn´t have to do this.
-
larsp777 wrote:
I have to add
Try without the attribute :)
Bastard Programmer from Hell :suss:
I have tried that and I get: The type was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically It works without derived classes but not when I try with derived classes. Also in my derived classes I declare another type of object. It´s a library-system. It has a List of book-objects. In the book-class I declare a customer-object in which I save the customer who borrows a book.
-
I have tried that and I get: The type was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically It works without derived classes but not when I try with derived classes. Also in my derived classes I declare another type of object. It´s a library-system. It has a List of book-objects. In the book-class I declare a customer-object in which I save the customer who borrows a book.
larsp777 wrote:
Also in my derived classes I declare another type of object. It´s a library-system. It has a List of book-objects.
I'd expect a List, not an object. Is that how it's declared?
larsp777 wrote:
It works without derived classes but not when I try with derived classes.
Found a similar issue here[^], has two solutions on the bottom of the page. I can't test them at the moment though, I'm not at home.
Bastard Programmer from Hell :suss:
-
larsp777 wrote:
Also in my derived classes I declare another type of object. It´s a library-system. It has a List of book-objects.
I'd expect a List, not an object. Is that how it's declared?
larsp777 wrote:
It works without derived classes but not when I try with derived classes.
Found a similar issue here[^], has two solutions on the bottom of the page. I can't test them at the moment though, I'm not at home.
Bastard Programmer from Hell :suss:
-
"I'd expect a List, not an object. Is that how it's declared?" Not sure what you mean but I declared a List of objects like: List BookList = new List();
larsp777 wrote:
Not sure what you mean but I declared a List of objects like:
List BookList = new List();I guess you "need" the attribute because it doesn't know what's going to be stored in the list (being objects). Can you post me a few lines more? If I put your code in a new project, I get a compile error (as expected, actually);
Error CS0246: The type or namespace name 'List' could not be found (are you missing a using directive or an assembly reference?)
I was expecting a generic list, from the namespace System.Collections.Generic;
System.Collection.Generic.List bookList =
new System.Collections.Generic.List();Sounds like the site that I linked in the previous post is right - which means that their solutions might work :)
Bastard Programmer from Hell :suss:
-
larsp777 wrote:
Not sure what you mean but I declared a List of objects like:
List BookList = new List();I guess you "need" the attribute because it doesn't know what's going to be stored in the list (being objects). Can you post me a few lines more? If I put your code in a new project, I get a compile error (as expected, actually);
Error CS0246: The type or namespace name 'List' could not be found (are you missing a using directive or an assembly reference?)
I was expecting a generic list, from the namespace System.Collections.Generic;
System.Collection.Generic.List bookList =
new System.Collections.Generic.List();Sounds like the site that I linked in the previous post is right - which means that their solutions might work :)
Bastard Programmer from Hell :suss:
-
Well, now I have to add an XmlInclude attribute to the Book parent class for each such sub-class. But as I understand it, the base-class shouldn´t have to know about the derived classes in OOP. As I remember in Java, you didn´t have to do this.
The BaseClass doesn't know anything about the subclasses, nor does it know what you're doing with them. The attributes on the members in the base class have nothing to do with OOP. Those attributes are specifically used by the XML Serializer, not any OOP definition.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
The BaseClass doesn't know anything about the subclasses, nor does it know what you're doing with them. The attributes on the members in the base class have nothing to do with OOP. Those attributes are specifically used by the XML Serializer, not any OOP definition.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
I have tested XmlSerializer but even if it works with derived classes I wonder if there isn´t a better way to save objects from derived classes. What I want to save is a List of derived objects.
There's a special constructor for the Xml serialiser to handle non-homogeneous lists
public XmlSerializer (Type type, Type[] extraTypes)
Basically this tells the serialiser about the main list type and any additional types it may encounter within the list. Code dump to show what I mean First generic serialiser/deserialiser methodspublic static String SerialiseToString<T>(T data, Type[] additionalTypes) {
XmlSerializer serializer = new XmlSerializer(typeof(T), additionalTypes);
using (StringWriter writer = new StringWriter()) {
serializer.Serialize(writer, data);
return writer.ToString();
}
}public static T DeserialiseFromString<T>(String xmlstr, Type[] additionalTypes) {
using (StringReader reader = new StringReader(xmlstr)) {
XmlSerializer serializer = new XmlSerializer(typeof(T), additionalTypes);
T temp = (T)serializer.Deserialize(reader);
return temp;
}
}Serialise a mixed list of Book and EBook as a test
List<Book> lst = new List<Book>();
Book one = new Book();one.Title = "Swallows and Amazons";
one.Author = "Arthur Ransome";
lst.Add(one);EBook two = new EBook();
two.Title = "War Horse";
two.Author = "Michael Morpurgo";
two.Platform = "Kindle";
lst.Add(two);
String xmlData = SerialiseToString<List<Book>>(lst, new Type[]{typeof(EBook)});Gives XML like this (I'm sure you've guessed the structure of the Book and derived EBook classes).
which can be deserialised correctly with
List<Book> lst = DeserialiseFromString<List<Book>>(xmlData, new Type[]{typeof(EBook)});
Alan.
-
It all depends on your requirements. There is no "best" way for all situations because "best" is a subjective evaluation.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
It all depends on your requirements. There is no "best" way for all situations because "best" is a subjective evaluation.
A guide to posting questions on CodeProject[^]
Dave KreskowiakOk. This is my situation right now. I have a bookclass. In it I declare a customerobjekt pointing to null. When I make a loan in my librarysystem a customer object is added to it so I know who is lending the book. In my Customerclass I have a book-list in which I save all the books the customer borrowed. As long as I doesn´t register a loan all is fine, and I can save both books and customer. But when I make a loan and have references to objects I ger circular reference. Is there a way around this?