Initial commit
[mono.git] / mcs / class / referencesource / mscorlib / system / collections / dictionarybase.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 //------------------------------------------------------------------------------
7 //------------------------------------------------------------------------------
8 // <OWNER>[....]</OWNER>
9 // 
10
11 namespace System.Collections {
12
13     using System;
14     using System.Security.Permissions;
15
16     // Useful base class for typed read/write collections where items derive from object
17     [Serializable]
18 [System.Runtime.InteropServices.ComVisible(true)]
19     public abstract class DictionaryBase : IDictionary {
20         Hashtable hashtable;
21
22         protected Hashtable InnerHashtable { 
23             get { 
24                 if (hashtable == null)
25                     hashtable = new Hashtable();
26                 return hashtable;
27             }
28         }
29
30         protected IDictionary Dictionary {
31             get { return (IDictionary) this; }
32         }
33
34         public int Count {
35             // to avoid newing inner list if no items are ever added
36             get { return hashtable == null ? 0 : hashtable.Count; }
37         }
38
39         bool IDictionary.IsReadOnly {
40             get { return InnerHashtable.IsReadOnly; }
41         }
42
43         bool IDictionary.IsFixedSize {
44             get { return InnerHashtable.IsFixedSize; }
45         }
46
47         bool ICollection.IsSynchronized {
48             get { return InnerHashtable.IsSynchronized; }
49         }
50
51         ICollection IDictionary.Keys {
52             get {
53                 return InnerHashtable.Keys;
54             }
55         }
56
57         Object ICollection.SyncRoot {
58             get { return InnerHashtable.SyncRoot; }
59         }
60
61         ICollection IDictionary.Values {
62             get {
63                 return InnerHashtable.Values;
64             }
65         }
66
67         public void CopyTo(Array array, int index) {
68             InnerHashtable.CopyTo(array, index);
69         }
70
71         object IDictionary.this[object key] {
72             get {
73                 object currentValue = InnerHashtable[key];
74                 OnGet(key, currentValue);
75                 return currentValue; 
76             }
77             set { 
78                 OnValidate(key, value);
79                 bool keyExists = true;
80                 Object temp = InnerHashtable[key];
81                 if( temp == null) {
82                     keyExists = InnerHashtable.Contains(key);
83                 }
84
85                 OnSet(key, temp, value); 
86                 InnerHashtable[key] = value; 
87                 try {
88                     OnSetComplete(key, temp, value); 
89                 }
90                 catch {
91                    if( keyExists) {
92                        InnerHashtable[key] = temp; 
93                    }
94                    else {
95                        InnerHashtable.Remove(key);
96                    }
97                    throw;
98                 }
99             }
100         }
101
102         bool IDictionary.Contains(object key) {
103             return InnerHashtable.Contains(key);
104         }
105
106         void IDictionary.Add(object key, object value) {
107             OnValidate(key, value);
108             OnInsert(key, value); 
109             InnerHashtable.Add(key, value);
110             try {
111                 OnInsertComplete(key, value);
112             }
113             catch {
114                 InnerHashtable.Remove(key);
115                 throw;
116             }
117         }
118
119         public void Clear() {
120             OnClear();
121             InnerHashtable.Clear();
122             OnClearComplete();
123         }
124
125         void IDictionary.Remove(object key) {
126             if(InnerHashtable.Contains(key)) {
127                 Object temp = InnerHashtable[key];
128                 OnValidate(key, temp);
129                 OnRemove(key, temp);
130
131                 InnerHashtable.Remove(key);
132                 try {
133                     OnRemoveComplete(key, temp);
134                 }
135                 catch {
136                     InnerHashtable.Add(key, temp);
137                     throw;
138                 }
139             }
140         }
141
142         public IDictionaryEnumerator GetEnumerator() {
143             return InnerHashtable.GetEnumerator();
144         }
145
146         IEnumerator IEnumerable.GetEnumerator() {
147             return InnerHashtable.GetEnumerator();
148         }
149
150         protected virtual object OnGet(object key, object currentValue) {
151             return currentValue;
152         }
153
154         protected virtual void OnSet(object key, object oldValue, object newValue) { 
155         }
156
157         protected virtual void OnInsert(object key, object value) { 
158         }
159
160         protected virtual void OnClear() { 
161         }
162
163         protected virtual void OnRemove(object key, object value) { 
164         }
165
166         protected virtual void OnValidate(object key, object value) {
167         }
168         
169         protected virtual void OnSetComplete(object key, object oldValue, object newValue) { 
170         }
171
172         protected virtual void OnInsertComplete(object key, object value) { 
173         }
174
175         protected virtual void OnClearComplete() { 
176         }
177
178         protected virtual void OnRemoveComplete(object key, object value) { 
179         }
180         
181     }
182
183 }