// // ReadOnlyDictionary.cs // // Authors: // Martin Baulig // Marek Safar (marek.safar@gmail.com) // // Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if NET_4_5 using System; using System.Collections.Generic; using System.Diagnostics; namespace System.Collections.ObjectModel { [Serializable] [DebuggerDisplay ("Count={Count}")] [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))] public class ReadOnlyDictionary : IDictionary, IDictionary, IReadOnlyDictionary { readonly IDictionary inner; public ReadOnlyDictionary (IDictionary dictionary) { if (dictionary == null) throw new ArgumentNullException ("dictionary"); this.inner = dictionary; } protected IDictionary Dictionary { get { return inner; } } public bool ContainsKey (TKey key) { return inner.ContainsKey (key); } public bool TryGetValue (TKey key, out TValue value) { return inner.TryGetValue (key, out value); } public TValue this [TKey key] { get { return inner [key]; } } public KeyCollection Keys { get { return new KeyCollection (inner.Keys); } } public ValueCollection Values { get { return new ValueCollection (inner.Values); } } #region IEnumerable> implementation public IEnumerator> GetEnumerator () { return inner.GetEnumerator (); } #endregion #region IEnumerable implementation IEnumerator IEnumerable.GetEnumerator () { return inner.GetEnumerator (); } #endregion #region IDictionary implementation void IDictionary.Add (TKey key, TValue value) { throw new NotSupportedException (); } bool IDictionary.Remove (TKey key) { throw new NotSupportedException (); } TValue IDictionary.this [TKey key] { get { return inner [key]; } set { throw new NotSupportedException (); } } ICollection IDictionary.Keys { get { return Keys; } } ICollection IDictionary.Values { get { return Values; } } #endregion #region IDictionary implementation void IDictionary.Add (object key, object value) { throw new NotSupportedException (); } void IDictionary.Clear () { throw new NotSupportedException (); } bool IDictionary.Contains (object key) { return ((IDictionary)inner).Contains (key); } IDictionaryEnumerator IDictionary.GetEnumerator () { return ((IDictionary)inner).GetEnumerator (); } void IDictionary.Remove (object key) { throw new NotSupportedException (); } bool IDictionary.IsFixedSize { get { return true; } } bool IDictionary.IsReadOnly { get { return true; } } object IDictionary.this [object key] { get { return ((IDictionary)inner)[key]; } set { throw new NotSupportedException (); } } ICollection IDictionary.Keys { get { return Keys; } } ICollection IDictionary.Values { get { return Values; } } #endregion #region ICollection implementation void ICollection.CopyTo (Array array, int index) { ((ICollection)inner).CopyTo (array, index); } #endregion #region ICollection> implementation void ICollection>.Add (KeyValuePair item) { throw new NotSupportedException (); } void ICollection>.Clear () { throw new NotSupportedException (); } bool ICollection>.Contains (KeyValuePair item) { return ((ICollection>)inner).Contains (item); } void ICollection>.CopyTo (KeyValuePair[] array, int arrayIndex) { ((ICollection>)inner).CopyTo (array, arrayIndex); } bool ICollection>.Remove (KeyValuePair item) { throw new NotSupportedException (); } bool ICollection>.IsReadOnly { get { return true; } } #endregion #region ICollection implementation public int Count { get { return inner.Count; } } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { throw new NotSupportedException (); } } #endregion IEnumerable IReadOnlyDictionary.Keys { get { return Keys; } } IEnumerable IReadOnlyDictionary.Values { get { return Values; } } [Serializable] [DebuggerDisplay ("Count={Count}")] [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))] public sealed class KeyCollection : ICollection, IEnumerable, ICollection, IEnumerable { readonly ICollection collection; internal KeyCollection (ICollection collection) { this.collection = collection; } public void CopyTo (TKey [] array, int arrayIndex) { collection.CopyTo (array, arrayIndex); } public IEnumerator GetEnumerator () { return collection.GetEnumerator (); } void ICollection.Add (TKey item) { throw new NotSupportedException ("this is a read-only collection"); } void ICollection.Clear () { throw new NotSupportedException ("this is a read-only collection"); } bool ICollection.Contains (TKey item) { return collection.Contains (item); } bool ICollection.Remove (TKey item) { throw new NotSupportedException ("this is a read-only collection"); } void ICollection.CopyTo (Array array, int index) { var target = array as TKey []; if (target != null) { CopyTo (target, index); return; } throw new NotImplementedException (); } IEnumerator IEnumerable.GetEnumerator () { return collection.GetEnumerator (); } public int Count { get { return collection.Count; } } bool ICollection.IsReadOnly { get { return true; } } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { throw new NotImplementedException (); } } } [Serializable] [DebuggerDisplay ("Count={Count}")] [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))] public sealed class ValueCollection : ICollection, IEnumerable, ICollection, IEnumerable { readonly ICollection collection; internal ValueCollection (ICollection collection) { this.collection = collection; } public void CopyTo (TValue [] array, int arrayIndex) { collection.CopyTo (array, arrayIndex); } public IEnumerator GetEnumerator () { return collection.GetEnumerator (); } void ICollection.Add (TValue item) { throw new NotSupportedException ("this is a read-only collection"); } void ICollection.Clear () { throw new NotSupportedException ("this is a read-only collection"); } bool ICollection.Contains (TValue item) { return collection.Contains (item); } bool ICollection.Remove (TValue item) { throw new NotSupportedException ("this is a read-only collection"); } void ICollection.CopyTo (Array array, int index) { var target = array as TValue []; if (target != null) { CopyTo (target, index); return; } throw new NotImplementedException (); } IEnumerator IEnumerable.GetEnumerator () { return collection.GetEnumerator (); } public int Count { get { return collection.Count; } } bool ICollection.IsReadOnly { get { return true; } } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { throw new NotImplementedException (); } } } } } #endif