**** Merged r40732-r40872 from MCS ****
[mono.git] / mcs / class / corlib / System.Collections / CollectionBase.cs
1 //\r
2 // System.Collections.CollectionBase.cs\r
3 //\r
4 // Author:\r
5 //   Nick Drochak II (ndrochak@gol.com)\r
6 //\r
7 // (C) 2001 Nick Drochak II\r
8 //\r
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 \r
33 using System;\r
34 \r
35 namespace System.Collections {\r
36 \r
37         [Serializable]\r
38         public abstract class CollectionBase : IList, ICollection, IEnumerable {\r
39 \r
40                 // private instance properties\r
41                 private ArrayList list;\r
42                 \r
43                 // public instance properties\r
44                 public int Count { get { return InnerList.Count; } }\r
45                 \r
46                 // Public Instance Methods\r
47                 public IEnumerator GetEnumerator() { return InnerList.GetEnumerator(); }\r
48                 public void Clear() { \r
49                         OnClear();\r
50                         InnerList.Clear(); \r
51                         OnClearComplete();\r
52                 }\r
53                 public void RemoveAt (int index) {\r
54                         object objectToRemove;\r
55                         objectToRemove = InnerList[index];\r
56                         OnValidate(objectToRemove);\r
57                         OnRemove(index, objectToRemove);\r
58                         InnerList.RemoveAt(index);\r
59                         OnRemoveComplete(index, objectToRemove);\r
60                 }\r
61                 \r
62                 // Protected Instance Constructors\r
63                 protected CollectionBase() { \r
64                         this.list = new ArrayList();\r
65                 }\r
66                 \r
67                 // Protected Instance Properties\r
68                 protected ArrayList InnerList {get { return this.list; } }\r
69                 protected IList List {get { return this; } }\r
70                 \r
71                 // Protected Instance Methods\r
72                 protected virtual void OnClear() { }\r
73                 protected virtual void OnClearComplete() { }\r
74                 \r
75                 protected virtual void OnInsert(int index, object value) { }\r
76                 protected virtual void OnInsertComplete(int index, object value) { }\r
77 \r
78                 protected virtual void OnRemove(int index, object value) { }\r
79                 protected virtual void OnRemoveComplete(int index, object value) { }\r
80 \r
81                 protected virtual void OnSet(int index, object oldValue, object newValue) { }\r
82                 protected virtual void OnSetComplete(int index, object oldValue, object newValue) { }\r
83 \r
84                 protected virtual void OnValidate(object value) {\r
85                         if (null == value) {\r
86                                 throw new System.ArgumentNullException("CollectionBase.OnValidate: Invalid parameter value passed to method: null");\r
87                         }\r
88                 }\r
89                 \r
90                 // ICollection methods\r
91                 void ICollection.CopyTo(Array array, int index) {\r
92                         InnerList.CopyTo(array, index);\r
93                 }\r
94                 object ICollection.SyncRoot {\r
95                         get { return InnerList.SyncRoot; }\r
96                 }\r
97                 bool ICollection.IsSynchronized {\r
98                         get { return InnerList.IsSynchronized; }\r
99                 }\r
100 \r
101                 // IList methods\r
102                 int IList.Add (object value) {\r
103                         int newPosition;\r
104                         OnValidate(value);\r
105                         newPosition = InnerList.Count;\r
106                         OnInsert(newPosition, value);\r
107                         InnerList.Add(value);\r
108                         try {\r
109                                 OnInsertComplete(newPosition, value);\r
110                         } catch {\r
111                                 InnerList.RemoveAt (newPosition);\r
112                                 throw;\r
113                         }\r
114                         \r
115                         return newPosition;\r
116                 }\r
117                 \r
118                 bool IList.Contains (object value) {\r
119                         return InnerList.Contains(value);\r
120                 }\r
121 \r
122                 int IList.IndexOf (object value) {\r
123                         return InnerList.IndexOf(value);\r
124                 }\r
125 \r
126                 void IList.Insert (int index, object value) {\r
127                         OnValidate(value);\r
128                         OnInsert(index, value);\r
129                         InnerList.Insert(index, value);\r
130                         try {\r
131                                 OnInsertComplete(index, value);\r
132                         } catch {\r
133                                 InnerList.RemoveAt (index);\r
134                                 throw;\r
135                         }\r
136                 }\r
137 \r
138                 void IList.Remove (object value) {\r
139                         int removeIndex;\r
140                         OnValidate(value);\r
141                         removeIndex = InnerList.IndexOf(value);\r
142                         if (removeIndex == -1)\r
143                                 throw new ArgumentException ("The element cannot be found.", "value");\r
144                         OnRemove(removeIndex, value);\r
145                         InnerList.Remove(value);\r
146                         OnRemoveComplete(removeIndex, value);\r
147                 }\r
148 \r
149                 // IList properties\r
150                 bool IList.IsFixedSize { \r
151                         get { return InnerList.IsFixedSize; }\r
152                 }\r
153 \r
154                 bool IList.IsReadOnly { \r
155                         get { return InnerList.IsReadOnly; }\r
156                 }\r
157 \r
158                 object IList.this[int index] { \r
159                         get { return InnerList[index]; }\r
160                         set { \r
161                                 if (index < 0 || index >= InnerList.Count)\r
162                                         throw new ArgumentOutOfRangeException ("index");\r
163 \r
164                                 object oldValue;\r
165                                 // make sure we have been given a valid value\r
166                                 OnValidate(value);\r
167                                 // save a reference to the object that is in the list now\r
168                                 oldValue = InnerList[index];\r
169                                 \r
170                                 OnSet(index, oldValue, value);\r
171                                 InnerList[index] = value;\r
172                                 try {\r
173                                         OnSetComplete(index, oldValue, value);\r
174                                 } catch {\r
175                                         InnerList[index] = oldValue;\r
176                                         throw;\r
177                                 }\r
178                         }\r
179                 }\r
180         }\r
181 }\r