ReadOnlyDictionary.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. //
  2. // ReadOnlyDictionary.cs
  3. //
  4. // Authors:
  5. // Martin Baulig <[email protected]>
  6. // Marek Safar ([email protected])
  7. //
  8. // Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining a copy
  11. // of this software and associated documentation files (the "Software"), to deal
  12. // in the Software without restriction, including without limitation the rights
  13. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. // copies of the Software, and to permit persons to whom the Software is
  15. // furnished to do so, subject to the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be included in
  18. // all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. // THE SOFTWARE.
  27. #if NET_4_5
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Diagnostics;
  31. namespace System.Collections.ObjectModel {
  32. [Serializable]
  33. [DebuggerDisplay ("Count={Count}")]
  34. [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))]
  35. public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary,
  36. IReadOnlyDictionary<TKey, TValue>
  37. {
  38. readonly IDictionary<TKey, TValue> inner;
  39. public ReadOnlyDictionary (IDictionary<TKey, TValue> dictionary)
  40. {
  41. if (dictionary == null)
  42. throw new ArgumentNullException ("dictionary");
  43. this.inner = dictionary;
  44. }
  45. protected IDictionary<TKey, TValue> Dictionary {
  46. get {
  47. return inner;
  48. }
  49. }
  50. public bool ContainsKey (TKey key)
  51. {
  52. return inner.ContainsKey (key);
  53. }
  54. public bool TryGetValue (TKey key, out TValue value)
  55. {
  56. return inner.TryGetValue (key, out value);
  57. }
  58. public TValue this [TKey key] {
  59. get {
  60. return inner [key];
  61. }
  62. }
  63. public KeyCollection Keys {
  64. get {
  65. return new KeyCollection (inner.Keys);
  66. }
  67. }
  68. public ValueCollection Values {
  69. get {
  70. return new ValueCollection (inner.Values);
  71. }
  72. }
  73. #region IEnumerable<KeyValuePair<TKey, TValue>> implementation
  74. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator ()
  75. {
  76. return inner.GetEnumerator ();
  77. }
  78. #endregion
  79. #region IEnumerable implementation
  80. IEnumerator IEnumerable.GetEnumerator ()
  81. {
  82. return inner.GetEnumerator ();
  83. }
  84. #endregion
  85. #region IDictionary<TKey, TValue> implementation
  86. void IDictionary<TKey, TValue>.Add (TKey key, TValue value)
  87. {
  88. throw new NotSupportedException ();
  89. }
  90. bool IDictionary<TKey, TValue>.Remove (TKey key)
  91. {
  92. throw new NotSupportedException ();
  93. }
  94. TValue IDictionary<TKey, TValue>.this [TKey key] {
  95. get {
  96. return inner [key];
  97. }
  98. set {
  99. throw new NotSupportedException ();
  100. }
  101. }
  102. ICollection<TKey> IDictionary<TKey, TValue>.Keys {
  103. get {
  104. return Keys;
  105. }
  106. }
  107. ICollection<TValue> IDictionary<TKey, TValue>.Values {
  108. get {
  109. return Values;
  110. }
  111. }
  112. #endregion
  113. #region IDictionary implementation
  114. void IDictionary.Add (object key, object value)
  115. {
  116. throw new NotSupportedException ();
  117. }
  118. void IDictionary.Clear ()
  119. {
  120. throw new NotSupportedException ();
  121. }
  122. bool IDictionary.Contains (object key)
  123. {
  124. return ((IDictionary)inner).Contains (key);
  125. }
  126. IDictionaryEnumerator IDictionary.GetEnumerator ()
  127. {
  128. return ((IDictionary)inner).GetEnumerator ();
  129. }
  130. void IDictionary.Remove (object key)
  131. {
  132. throw new NotSupportedException ();
  133. }
  134. bool IDictionary.IsFixedSize {
  135. get {
  136. return true;
  137. }
  138. }
  139. bool IDictionary.IsReadOnly {
  140. get {
  141. return true;
  142. }
  143. }
  144. object IDictionary.this [object key] {
  145. get {
  146. return ((IDictionary)inner)[key];
  147. }
  148. set {
  149. throw new NotSupportedException ();
  150. }
  151. }
  152. ICollection IDictionary.Keys {
  153. get {
  154. return Keys;
  155. }
  156. }
  157. ICollection IDictionary.Values {
  158. get {
  159. return Values;
  160. }
  161. }
  162. #endregion
  163. #region ICollection implementation
  164. void ICollection.CopyTo (Array array, int index)
  165. {
  166. ((ICollection)inner).CopyTo (array, index);
  167. }
  168. #endregion
  169. #region ICollection<KeyValuePair<TKey, TValue>> implementation
  170. void ICollection<KeyValuePair<TKey, TValue>>.Add (KeyValuePair<TKey, TValue> item)
  171. {
  172. throw new NotSupportedException ();
  173. }
  174. void ICollection<KeyValuePair<TKey, TValue>>.Clear ()
  175. {
  176. throw new NotSupportedException ();
  177. }
  178. bool ICollection<KeyValuePair<TKey, TValue>>.Contains (KeyValuePair<TKey, TValue> item)
  179. {
  180. return ((ICollection<KeyValuePair<TKey, TValue>>)inner).Contains (item);
  181. }
  182. void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array, int arrayIndex)
  183. {
  184. ((ICollection<KeyValuePair<TKey, TValue>>)inner).CopyTo (array, arrayIndex);
  185. }
  186. bool ICollection<KeyValuePair<TKey, TValue>>.Remove (KeyValuePair<TKey, TValue> item)
  187. {
  188. throw new NotSupportedException ();
  189. }
  190. bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
  191. get {
  192. return true;
  193. }
  194. }
  195. #endregion
  196. #region ICollection implementation
  197. public int Count {
  198. get {
  199. return inner.Count;
  200. }
  201. }
  202. bool ICollection.IsSynchronized {
  203. get {
  204. return false;
  205. }
  206. }
  207. object ICollection.SyncRoot {
  208. get {
  209. throw new NotSupportedException ();
  210. }
  211. }
  212. #endregion
  213. IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys {
  214. get {
  215. return Keys;
  216. }
  217. }
  218. IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values {
  219. get {
  220. return Values;
  221. }
  222. }
  223. [Serializable]
  224. [DebuggerDisplay ("Count={Count}")]
  225. [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))]
  226. public sealed class KeyCollection : ICollection<TKey>, IEnumerable<TKey>, ICollection, IEnumerable
  227. {
  228. readonly ICollection<TKey> collection;
  229. internal KeyCollection (ICollection<TKey> collection)
  230. {
  231. this.collection = collection;
  232. }
  233. public void CopyTo (TKey [] array, int arrayIndex)
  234. {
  235. collection.CopyTo (array, arrayIndex);
  236. }
  237. public IEnumerator<TKey> GetEnumerator ()
  238. {
  239. return collection.GetEnumerator ();
  240. }
  241. void ICollection<TKey>.Add (TKey item)
  242. {
  243. throw new NotSupportedException ("this is a read-only collection");
  244. }
  245. void ICollection<TKey>.Clear ()
  246. {
  247. throw new NotSupportedException ("this is a read-only collection");
  248. }
  249. bool ICollection<TKey>.Contains (TKey item)
  250. {
  251. return collection.Contains (item);
  252. }
  253. bool ICollection<TKey>.Remove (TKey item)
  254. {
  255. throw new NotSupportedException ("this is a read-only collection");
  256. }
  257. void ICollection.CopyTo (Array array, int index)
  258. {
  259. var target = array as TKey [];
  260. if (target != null) {
  261. CopyTo (target, index);
  262. return;
  263. }
  264. throw new NotImplementedException ();
  265. }
  266. IEnumerator IEnumerable.GetEnumerator ()
  267. {
  268. return collection.GetEnumerator ();
  269. }
  270. public int Count {
  271. get {
  272. return collection.Count;
  273. }
  274. }
  275. bool ICollection<TKey>.IsReadOnly {
  276. get {
  277. return true;
  278. }
  279. }
  280. bool ICollection.IsSynchronized {
  281. get {
  282. return false;
  283. }
  284. }
  285. object ICollection.SyncRoot {
  286. get {
  287. throw new NotImplementedException ();
  288. }
  289. }
  290. }
  291. [Serializable]
  292. [DebuggerDisplay ("Count={Count}")]
  293. [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))]
  294. public sealed class ValueCollection : ICollection<TValue>, IEnumerable<TValue>, ICollection, IEnumerable
  295. {
  296. readonly ICollection<TValue> collection;
  297. internal ValueCollection (ICollection<TValue> collection)
  298. {
  299. this.collection = collection;
  300. }
  301. public void CopyTo (TValue [] array, int arrayIndex)
  302. {
  303. collection.CopyTo (array, arrayIndex);
  304. }
  305. public IEnumerator<TValue> GetEnumerator ()
  306. {
  307. return collection.GetEnumerator ();
  308. }
  309. void ICollection<TValue>.Add (TValue item)
  310. {
  311. throw new NotSupportedException ("this is a read-only collection");
  312. }
  313. void ICollection<TValue>.Clear ()
  314. {
  315. throw new NotSupportedException ("this is a read-only collection");
  316. }
  317. bool ICollection<TValue>.Contains (TValue item)
  318. {
  319. return collection.Contains (item);
  320. }
  321. bool ICollection<TValue>.Remove (TValue item)
  322. {
  323. throw new NotSupportedException ("this is a read-only collection");
  324. }
  325. void ICollection.CopyTo (Array array, int index)
  326. {
  327. var target = array as TValue [];
  328. if (target != null) {
  329. CopyTo (target, index);
  330. return;
  331. }
  332. throw new NotImplementedException ();
  333. }
  334. IEnumerator IEnumerable.GetEnumerator ()
  335. {
  336. return collection.GetEnumerator ();
  337. }
  338. public int Count {
  339. get {
  340. return collection.Count;
  341. }
  342. }
  343. bool ICollection<TValue>.IsReadOnly {
  344. get {
  345. return true;
  346. }
  347. }
  348. bool ICollection.IsSynchronized {
  349. get {
  350. return false;
  351. }
  352. }
  353. object ICollection.SyncRoot {
  354. get {
  355. throw new NotImplementedException ();
  356. }
  357. }
  358. }
  359. }
  360. }
  361. #endif