You are hereC# Tips and Trick / XML Serialization of Containers and Dictionaries

XML Serialization of Containers and Dictionaries


By Rick Sprenkle - Posted on 17 January 2011

This is a console app example (see void Main) where we test two helper classes:

  • CollectionSerializer<T> which can serialize a list of T objects via XML
  • DictionarySerializer<Tkey, Tvalue> which can serialize a Dictionary via XML, bypasssing the .NET serialization limitations of Dictionaries by serializing the Keys and Values as separate Lists.
A copy of this file is attached to this page
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
   class Program
    {
        static void Main(string[] args)
        {
            CollectionSerializer<string> stringSerializer = new CollectionSerializer<string>();
            stringSerializer.ObjectList.Add("One");
            stringSerializer.ObjectList.Add("Two");
            stringSerializer.SaveXML(@"E:\Test.xml");
 
            CollectionSerializer<string> stringSerializer2 = CollectionSerializer<string>.LoadXML(@"E:\Test.xml");
 
          
            DictionarySerializer<string, int> intDictionarySerializer = new DictionarySerializer<string, int>();
            intDictionarySerializer.Add("One", 1);
            intDictionarySerializer.Add("Two", 2);
            intDictionarySerializer.SaveXML(@"E:\Test2.xml");
            DictionarySerializer<string, int> intDictionarySerializer2 = DictionarySerializer<string, int>.LoadXML(@"E:\Test2.xml");
            Dictionary<string, int> dictionary = intDictionarySerializer2.Dictionary;
 
        }
    }
 
 
    public class CollectionSerializer<T>
    {
   
        private List<T> _objectList = new List<T>();
 
   
        public List<T> ObjectList
        {
            get { return _objectList; }
            set { _objectList = value; }
        }
 
        public void SaveXML(string filename)
        {
 
            XmlSerializer serializer = new XmlSerializer(typeof(CollectionSerializer<T>));
            using (StreamWriter streamWriter = new StreamWriter(filename, false))
            {
                serializer.Serialize(streamWriter, this);
            }
 
        }
 
        public static CollectionSerializer<T> LoadXML(string filename)
        {
 
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(CollectionSerializer<T>));
            using (System.IO.StreamReader streamReader = new StreamReader(filename))
            {
                return (CollectionSerializer<T>)serializer.Deserialize(streamReader);
            }
 
        }
 
 
    }
 
    public class DictionarySerializer<Tkey,Tvalue>
    {
        [NonSerialized]
        [XmlIgnore]
        bool _isDirty = false;
 
        [NonSerialized]
        [XmlIgnore]
        private Dictionary<Tkey, Tvalue> _objectList ;
 
        [XmlIgnore]
        public Dictionary<Tkey, Tvalue> Dictionary
        {
            get 
            {
                if (_objectList == null)
                {
                    _isDirty = false;
 
                    if(_keys == null || _values == null)
                        return null;
     
                    if(_keys.Count != _values.Count)
                        throw new InvalidDataException("Keys and Values Count are not the same");
 
                    int count = _keys.Count;
                    _objectList = new Dictionary<Tkey, Tvalue>(count);
                    for (int i = 0; i < count; i++)
                    {
                        _objectList.Add(_keys[i], _values[i]);
                    }
                }
                else if (_isDirty)
                {
                    _isDirty = false;
                    _objectList.Clear();
                    _objectList = null;
                    return Dictionary;
                }
                return _objectList; 
            }
            set 
            {
                _isDirty = false;
                _objectList = value;
                _keys = new List<Tkey>();
                _values = new List<Tvalue>();
                foreach (Tkey key in value.Keys)
                {
                    _keys.Add(key);
                }
                foreach (Tvalue val in value.Values)
                {
                    _values.Add(val);
                }
            }
        }
 
        public void Add(Tkey key, Tvalue value)
        {
            _isDirty = true;
            if (_keys == null)
                _keys = new List<Tkey>();
            if (_values == null)
                _values = new List<Tvalue>();
 
            _keys.Add(key);
 
            _values.Add(value);
        }
 
        private List<Tkey> _keys;
 
        public List<Tkey> Keys
        {
            get { return _keys; }
            set 
            {
                _isDirty = true;
                _keys = value; 
            }
        }
 
        private List<Tvalue> _values;
 
        public List<Tvalue> Values
        {
            get { return _values; }
            set 
            {
                _isDirty = true;
                _values = value; 
            }
        }
 
 
        public void SaveXML(string filename)
        {
 
            XmlSerializer serializer = new XmlSerializer(typeof(DictionarySerializer<Tkey, Tvalue>));
            using (StreamWriter streamWriter = new StreamWriter(filename, false))
            {
                serializer.Serialize(streamWriter, this);
            }
 
        }
 
        public static DictionarySerializer<Tkey, Tvalue> LoadXML(string filename)
        {
 
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(DictionarySerializer<Tkey, Tvalue>));
            using (System.IO.StreamReader streamReader = new StreamReader(filename))
            {
                return (DictionarySerializer<Tkey, Tvalue>)serializer.Deserialize(streamReader);
            }
 
        }
 
 
    }