Facilitate the merge
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Scripting.Core / Utils / ReadOnlyDictionary.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Microsoft Public License. A 
6  * copy of the license can be found in the License.html file at the root of this distribution. If 
7  * you cannot locate the  Microsoft Public License, please send an email to 
8  * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Microsoft Public License.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 #if CLR2
17 using Microsoft.Scripting.Ast;
18 #else
19 using System.Linq.Expressions;
20 #endif
21 #if SILVERLIGHT
22 using System.Core;
23 #endif
24
25 using System.Collections.Generic;
26
27 namespace System.Dynamic.Utils {
28
29     // Like ReadOnlyCollection<T>: wraps an IDictionary<K, V> in a read-only wrapper
30     internal sealed class ReadOnlyDictionary<K, V> : IDictionary<K, V> {
31
32         // For wrapping non-readonly Keys, Values collections
33         // Not used for standard dictionaries, which return read-only Keys and Values
34         private sealed class ReadOnlyWrapper<T> : ICollection<T> {
35             // no idea why this warning is here
36             [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
37             private readonly ICollection<T> _collection;
38             
39             internal ReadOnlyWrapper(ICollection<T> collection) {
40                 _collection = collection;
41             }
42
43             #region ICollection<T> Members
44
45             public void Add(T item) {
46                 throw Error.CollectionReadOnly();
47             }
48
49             public void Clear() {
50                 throw Error.CollectionReadOnly();
51             }
52
53             public bool Contains(T item) {
54                 return _collection.Contains(item);
55             }
56
57             public void CopyTo(T[] array, int arrayIndex) {
58                 _collection.CopyTo(array, arrayIndex);
59             }
60
61             public int Count {
62                 get { return _collection.Count; }
63             }
64
65             public bool IsReadOnly {
66                 get { return true; }
67             }
68
69             public bool Remove(T item) {
70                 throw Error.CollectionReadOnly();
71             }
72
73             #endregion
74
75             #region IEnumerable<T> Members
76
77             public IEnumerator<T> GetEnumerator() {
78                 return _collection.GetEnumerator();
79             }
80
81             #endregion
82
83             #region IEnumerable Members
84
85             System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
86                 return _collection.GetEnumerator();
87             }
88
89             #endregion
90         }
91
92         private readonly IDictionary<K, V> _dict;
93
94         internal ReadOnlyDictionary(IDictionary<K, V> dict) {
95             ReadOnlyDictionary<K, V> rodict = dict as ReadOnlyDictionary<K, V>;
96             _dict = (rodict != null) ? rodict._dict : dict;
97         }
98
99         #region IDictionary<K,V> Members
100
101         public bool ContainsKey(K key) {
102             return _dict.ContainsKey(key);
103         }
104
105         public ICollection<K> Keys {
106             get {
107                 ICollection<K> keys = _dict.Keys;
108                 if (!keys.IsReadOnly) {
109                     return new ReadOnlyWrapper<K>(keys);
110                 }
111                 return keys;
112             }
113         }
114
115         public bool TryGetValue(K key, out V value) {
116             return _dict.TryGetValue(key, out value);
117         }
118
119         public ICollection<V> Values {
120             get {
121                 ICollection<V> values = _dict.Values;
122                 if (!values.IsReadOnly) {
123                     return new ReadOnlyWrapper<V>(values);
124                 }
125                 return values;
126             }
127         }
128
129         public V this[K key] {
130             get {
131                 return _dict[key];
132             }
133         }
134
135
136         void IDictionary<K, V>.Add(K key, V value) {
137             throw Error.CollectionReadOnly();
138         }
139
140         bool IDictionary<K, V>.Remove(K key) {
141             throw Error.CollectionReadOnly();
142         }
143
144         V IDictionary<K, V>.this[K key] {
145             get {
146                 return _dict[key];
147             }
148             set {
149                 throw Error.CollectionReadOnly();
150             }
151         }
152
153         #endregion
154
155         #region ICollection<KeyValuePair<K,V>> Members
156
157         public bool Contains(KeyValuePair<K, V> item) {
158             return _dict.Contains(item);
159         }
160
161         public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) {
162             _dict.CopyTo(array, arrayIndex);
163         }
164
165         public int Count {
166             get { return _dict.Count; }
167         }
168
169         public bool IsReadOnly {
170             get { return true; }
171         }
172
173         void ICollection<KeyValuePair<K, V>>.Add(KeyValuePair<K, V> item) {
174             throw Error.CollectionReadOnly();
175         }
176
177         void ICollection<KeyValuePair<K, V>>.Clear() {
178             throw Error.CollectionReadOnly();
179         }
180
181         bool ICollection<KeyValuePair<K,V>>.Remove(KeyValuePair<K, V> item) {
182             throw Error.CollectionReadOnly();
183         }
184
185         #endregion
186
187         #region IEnumerable<KeyValuePair<K,V>> Members
188
189         public IEnumerator<KeyValuePair<K, V>> GetEnumerator() {
190             return _dict.GetEnumerator();
191         }
192
193         #endregion
194
195         #region IEnumerable Members
196
197         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
198             return _dict.GetEnumerator();
199         }
200
201         #endregion
202     }
203 }