Possible Duplicate:
Why XML-Serializable class need a parameterless constructor
I'm trying to serialize a tuple in my code:
List<List<Tuple<String, CodeExtractor.StatementNode>>> results = null; results = extractor.ExtractSourceCode(sourceCode); FileStream fs = new FileStream(@"C:\Projects\Test\ast.xml", FileMode.Create); XmlSerializer formatter = new XmlSerializer( typeof(List<List<Tuple<String, CodeExtractor.StatementNode>>>)); formatter.Serialize(fs, results); fs.Close();
but it was failed and catch the exception like this:
System.Tuple`2[System.String,CodeExtractor.StatementNode] cannot be serialized because it does not have a parameterless constructor.
and I'm do sure the CodeExtractor.StatementNode
could be serialized.
Summary. Class Foo with Tuple data, can be serialized to json string, and the string can be deserialized back to Class Foo .
Python tuples are JSON serializable, just like lists or dictionaries. The JSONEncoder class supports the following objects and types by default. The process of converting a tuple (or any other native Python object) to a JSON string is called serialization.
It is not future-proof for small changes If you mark your classes as [Serializable] , then all the private data not marked as [NonSerialized] will get dumped. You have no control over the format of this data. If you change the name of a private variable, then your code will break.
Serialize datetime by converting it into String You can convert dateTime value into its String representation and encode it directly, here you don't need to write any encoder. We need to set the default parameter of a json. dump() or json. dumps() to str like this json.
For XmlSerializer
to be able to do its job it needs a default contructor. That is a constructor that takes no arguments. All the Tuple<...>
classes have a single constructor and that constructor takes a number of arguments. One for each value in the tuple. So in your case the sole constructor is
Tuple(T1 value1, T2 value2)
The serializer is looking for a constructor with no arguments and because it can't find it, you get the exception.
you could create a mutable class, that could be substituted for tuples for the purpose of serialization
class MyTuple<T1, T2> { MyTuple() { } public T1 Item1 { get; set; } public T2 Item2 { get; set; } public static implicit operator MyTuple<T1, T2>(Tuple<T1, T2> t) { return new MyTuple<T1, T2>(){ Item1 = t.Item1, Item2 = t.Item2 }; } public static implicit operator Tuple<T1, T2>(MyTuple<T1, T2> t) { return Tuple.Create(t.Item1, t.Item2); } }
You could then use it the following way
XmlSerializer formatter = new XmlSerializer( typeof(List<List<MyTuple<String, CodeExtractor.StatementNode>>>)); formatter.Serialize(fs, results.SelectMany( lst => lst.Select( t => (MyTuple)t ).ToList() ).ToList());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With