2

Because I haven't found a better way to handle my configuration, I have been using XmlSerializer to serialize a Dictionary (explain that later) containing all the things I want saved. Now that I have gotten more crafty, I have started to build more complex data types. The only problem is that now when I serialize the object, it throws an error because its not a primitive data type. If I make a new serializer for every value, I then cannot load the object back. Is there an easy way around this? Or an easy library for saving and loading any data type.

The Serializable Dictionary. I'm using <string,object> for <T,S>

public void ReadXml (System.Xml.XmlReader reader)
{
 try {
  XmlSerializer deserializerKeys = new XmlSerializer( typeof(T) );
  XmlSerializer deserializerValues = new XmlSerializer( typeof(S) );
  reader.Read();
  while (true) {
   T key = (T)deserializerKeys.Deserialize(reader);
   S val = (S)deserializerValues.Deserialize(reader); // fail :(
   this.Add( key, val );
  }
 } catch ( Exception e ) {
  Console.WriteLine( e.Message );
  Console.WriteLine( e.StackTrace );
 }
}


public void WriteXml (System.Xml.XmlWriter writer)
{
    // ONE OF THE serializerValues is always commented out
    // Im just showing the two ways I have done this
 XmlSerializer serializerKeys = new XmlSerializer( typeof( T ) );
    // this works for loading but not for saving >.>
 XmlSerializer serializerValues = new XmlSerializer( typeof( S ) );
 foreach ( KeyValuePair<T,S> pair in this ) {
        // this way works with the saving but fails with loading
  XmlSerializer serializerValues = new XmlSerializer(pair.Value.GetType());
  serializerKeys.Serialize( writer, pair.Key );
  serializerValues.Serialize( writer, pair.Value );
 }
}

Then I have another class that is derived from List<SimpleRegex>, it holds all the SimpleRegex objects and a "selected regex". The SimpleRegex is just a class that holds a simpler regex syntax and provides the same sort of methods a normal regex would(match, replace, etc.). That way, normal people can use it. This RegexCollection (the List<SimpleRegex>) is not primitive. That is my problem. Basically, all I want to do is save and load any data type.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
David Stocking
  • 1,200
  • 15
  • 26
  • Saving and loading of an *arbitrary* data type simply isn't possible - *all* serializers place some conditions on your data. @Jalal gives a reasonable description of using `BinaryFormatter`, which has an advantage that it will let you work with `object` (since `BinaryFormatter` writes the full type details into the stream), but *personally* I would say simply: don't use `object` here: know what your data is instead. – Marc Gravell Jul 09 '10 at 05:40
  • If I just made it a variable would `XmlSerializer( typeof(Config) )` auto figure out how to serialize RegexCollection? So....Is the XmlSerializer sort of recursive in serializing? GAR do you get what I mean? – David Stocking Jul 09 '10 at 05:59
  • as long as your `Config` type makes it clear (via properties etc) that it needs `RegexCollection`, and as long as `RegexCollection` is an easy to understand list, and as long as `SimpleRegex` has mutable properties, and all the types are public and all have public constructors.... then yes. There are other serializers that place fewer demands, of course. – Marc Gravell Jul 09 '10 at 06:20
  • @Marc Gravell Well, even though I hate typing guess its what I'm going to have to do. Guess its what I get for trying to program like a smart ass :) – David Stocking Jul 09 '10 at 06:41

1 Answers1

2

Using XML Serialization have some conditions:

  • It can't serialize Multidimensional arrays
  • The class which is going to serialize should have a constructor without any argument.

Any data type will not be serialize with XML Serializer...

Use Binary Serializer

public void SerializeObject(string filename, Object o)
{
    Stream stream = File.Open(filename, FileMode.Create);
    BinaryFormatter bFormatter = new BinaryFormatter();
    bFormatter.Serialize(stream, o);
    stream.Close();
}

and binary deserializer

    public object DeserializeObject(string filename)
    {
        object o;
        Stream stream = File.Open(filename, FileMode.Open);
        BinaryFormatter bFormatter = new BinaryFormatter();
        o = (ObjectToSerialize)bFormatter.Deserialize(stream);
        stream.Close();
        return o;
    }
Jalal
  • 6,594
  • 9
  • 63
  • 100
  • Well, XML Serializer definitely can serialize arrays. – Yury Tarabanko Jul 09 '10 at 05:05
  • 1
    I know I keep on about it, but `BinaryFormatter` is **not** a great choice for anything that is getting persisted, for example to disk (or a db). The only thing it has in its favor here is that it works with `object`. My take there would be "don't use `object` here - know the data up-front". And `BinaryFormatter` *also* has demands - for example that your type is `ISerializable` or `[Serializable]`. – Marc Gravell Jul 09 '10 at 05:36
  • Thanks, but I mean Multidimensional arrays! Following exception rise for Multidimensional arrays while Xml Serializing: "Cannot serialize object of type System.Int32[,]. Multidimensional arrays are not supported." But recommended use XML Serialize for saving configuration... – Jalal Jul 11 '10 at 06:13