Fix serialization issue
[mono.git] / mcs / class / corlib / System.Collections / CollectionBase.cs
1 //
2 // System.Collections.CollectionBase.cs
3 //
4 // Author:
5 //   Nick Drochak II (ndrochak@gol.com)
6 //
7 // (C) 2001 Nick Drochak II
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Runtime.InteropServices;
35
36 namespace System.Collections {
37
38         [ComVisible(true)]
39         [Serializable]
40         [System.Diagnostics.DebuggerDisplay ("Count={Count}")]
41         [System.Diagnostics.DebuggerTypeProxy (typeof (CollectionDebuggerView))]
42 #if INSIDE_CORLIB
43         public
44 #else
45         internal
46 #endif
47         abstract class CollectionBase : IList, ICollection, IEnumerable {
48
49                 // private instance properties
50                 private ArrayList list;
51                 
52                 // public instance properties
53                 public int Count { get { return InnerList.Count; } }
54                 
55                 // Public Instance Methods
56                 public IEnumerator GetEnumerator() { return InnerList.GetEnumerator(); }
57                 public void Clear() { 
58                         OnClear();
59                         InnerList.Clear(); 
60                         OnClearComplete();
61                 }
62                 public void RemoveAt (int index) {
63                         object objectToRemove;
64                         objectToRemove = InnerList[index];
65                         OnValidate(objectToRemove);
66                         OnRemove(index, objectToRemove);
67                         InnerList.RemoveAt(index);
68                         OnRemoveComplete(index, objectToRemove);
69                 }
70                 
71                 // Protected Instance Constructors
72                 protected CollectionBase()
73                 { 
74                 }
75
76                 protected CollectionBase (int capacity)
77                 {
78                         list = new ArrayList (capacity);
79                 }
80
81                 [ComVisible (false)]
82                 public int Capacity {
83                         get {
84                                 if (list == null)
85                                         list = new ArrayList ();
86                                 
87                                 return list.Capacity;
88                         }
89
90                         set {
91                                 if (list == null)
92                                         list = new ArrayList ();
93                                                               
94                                 list.Capacity = value;
95                         }
96                 }
97                 
98                 // Protected Instance Properties
99                 protected ArrayList InnerList {
100                         get {
101                                 if (list == null)
102                                         list = new ArrayList ();
103                                 return list;
104                         } 
105                 }
106                 
107                 protected IList List {get { return this; } }
108                 
109                 // Protected Instance Methods
110                 protected virtual void OnClear() { }
111                 protected virtual void OnClearComplete() { }
112                 
113                 protected virtual void OnInsert(int index, object value) { }
114                 protected virtual void OnInsertComplete(int index, object value) { }
115
116                 protected virtual void OnRemove(int index, object value) { }
117                 protected virtual void OnRemoveComplete(int index, object value) { }
118
119                 protected virtual void OnSet(int index, object oldValue, object newValue) { }
120                 protected virtual void OnSetComplete(int index, object oldValue, object newValue) { }
121
122                 protected virtual void OnValidate(object value) {
123                         if (null == value) {
124                                 throw new System.ArgumentNullException("CollectionBase.OnValidate: Invalid parameter value passed to method: null");
125                         }
126                 }
127                 
128                 // ICollection methods
129                 void ICollection.CopyTo(Array array, int index) {
130                         InnerList.CopyTo(array, index);
131                 }
132                 object ICollection.SyncRoot {
133                         get { return InnerList.SyncRoot; }
134                 }
135                 bool ICollection.IsSynchronized {
136                         get { return InnerList.IsSynchronized; }
137                 }
138
139                 // IList methods
140                 int IList.Add (object value) {
141                         int newPosition;
142                         OnValidate(value);
143                         newPosition = InnerList.Count;
144                         OnInsert(newPosition, value);
145                         InnerList.Add(value);
146                         try {
147                                 OnInsertComplete(newPosition, value);
148                         } catch {
149                                 InnerList.RemoveAt (newPosition);
150                                 throw;
151                         }
152                         
153                         return newPosition;
154                 }
155                 
156                 bool IList.Contains (object value) {
157                         return InnerList.Contains(value);
158                 }
159
160                 int IList.IndexOf (object value) {
161                         return InnerList.IndexOf(value);
162                 }
163
164                 void IList.Insert (int index, object value) {
165                         OnValidate(value);
166                         OnInsert(index, value);
167                         InnerList.Insert(index, value);
168                         try {
169                                 OnInsertComplete(index, value);
170                         } catch {
171                                 InnerList.RemoveAt (index);
172                                 throw;
173                         }
174                 }
175
176                 void IList.Remove (object value) {
177                         int removeIndex;
178                         OnValidate(value);
179                         removeIndex = InnerList.IndexOf(value);
180                         if (removeIndex == -1)
181                                 throw new ArgumentException ("The element cannot be found.", "value");
182                         OnRemove(removeIndex, value);
183                         InnerList.Remove(value);
184                         OnRemoveComplete(removeIndex, value);
185                 }
186
187                 // IList properties
188                 bool IList.IsFixedSize { 
189                         get { return InnerList.IsFixedSize; }
190                 }
191
192                 bool IList.IsReadOnly { 
193                         get { return InnerList.IsReadOnly; }
194                 }
195
196                 object IList.this[int index] { 
197                         get { return InnerList[index]; }
198                         set { 
199                                 if (index < 0 || index >= InnerList.Count)
200                                         throw new ArgumentOutOfRangeException ("index");
201
202                                 object oldValue;
203                                 // make sure we have been given a valid value
204                                 OnValidate(value);
205                                 // save a reference to the object that is in the list now
206                                 oldValue = InnerList[index];
207                                 
208                                 OnSet(index, oldValue, value);
209                                 InnerList[index] = value;
210                                 try {
211                                         OnSetComplete(index, oldValue, value);
212                                 } catch {
213                                         InnerList[index] = oldValue;
214                                         throw;
215                                 }
216                         }
217                 }
218         }
219 }