#region CPL License /* Nuclex Framework Copyright (C) 2002-2012 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion using System; using System.Collections.Generic; using System.Collections; using System.Collections.ObjectModel; using System.Runtime.Serialization; namespace Nuclex.Support.Collections { /// Wraps a dictionary and prevents users from modifying it /// Type of the keys used in the dictionary /// Type of the values used in the dictionary #if !NO_SERIALIZATION [Serializable] #endif public class ReadOnlyDictionary : #if !NO_SERIALIZATION ISerializable, IDeserializationCallback, #endif IDictionary, IDictionary { #if !NO_SERIALIZATION #region class SerializedDictionary /// /// Dictionary wrapped used to reconstruct a serialized read only dictionary /// private class SerializedDictionary : Dictionary { /// /// Initializes a new instance of the System.WeakReference class, using deserialized /// data from the specified serialization and stream objects. /// /// /// An object that holds all the data needed to serialize or deserialize the /// current System.WeakReference object. /// /// /// (Reserved) Describes the source and destination of the serialized stream /// specified by info. /// /// /// The info parameter is null. /// public SerializedDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { } } #endregion // class SerializedDictionary /// /// Initializes a new instance of the System.WeakReference class, using deserialized /// data from the specified serialization and stream objects. /// /// /// An object that holds all the data needed to serialize or deserialize the /// current System.WeakReference object. /// /// /// (Reserved) Describes the source and destination of the serialized stream /// specified by info. /// /// /// The info parameter is null. /// protected ReadOnlyDictionary(SerializationInfo info, StreamingContext context) : this(new SerializedDictionary(info, context)) { } #endif // !NO_SERIALIZATION /// Initializes a new read-only dictionary wrapper /// Dictionary that will be wrapped public ReadOnlyDictionary(IDictionary dictionary) { this.typedDictionary = dictionary; this.objectDictionary = (this.typedDictionary as IDictionary); } /// Whether the directory is write-protected public bool IsReadOnly { get { return true; } } /// /// Determines whether the specified KeyValuePair is contained in the Dictionary /// /// KeyValuePair that will be checked for /// True if the provided KeyValuePair was contained in the Dictionary public bool Contains(KeyValuePair item) { return this.typedDictionary.Contains(item); } /// Determines whether the Dictionary contains the specified key /// Key that will be checked for /// /// True if an entry with the specified key was contained in the Dictionary /// public bool ContainsKey(KeyType key) { return this.typedDictionary.ContainsKey(key); } /// Copies the contents of the Dictionary into an array /// Array the Dictionary will be copied into /// /// Starting index at which to begin filling the destination array /// public void CopyTo(KeyValuePair[] array, int arrayIndex) { this.typedDictionary.CopyTo(array, arrayIndex); } /// Number of elements contained in the Dictionary public int Count { get { return this.typedDictionary.Count; } } /// Creates a new enumerator for the Dictionary /// The new Dictionary enumerator public IEnumerator> GetEnumerator() { return this.typedDictionary.GetEnumerator(); } /// Collection of all keys contained in the Dictionary public ICollection Keys { get { if(this.readonlyKeyCollection == null) { this.readonlyKeyCollection = new ReadOnlyCollection( this.typedDictionary.Keys ); } return this.readonlyKeyCollection; } } /// Collection of all values contained in the Dictionary public ICollection Values { get { if(this.readonlyValueCollection == null) { this.readonlyValueCollection = new ReadOnlyCollection( this.typedDictionary.Values ); } return this.readonlyValueCollection; } } /// /// Attempts to retrieve the item with the specified key from the Dictionary /// /// Key of the item to attempt to retrieve /// /// Output parameter that will receive the key upon successful completion /// /// /// True if the item was found and has been placed in the output parameter /// public bool TryGetValue(KeyType key, out ValueType value) { return this.typedDictionary.TryGetValue(key, out value); } /// Accesses an item in the Dictionary by its key /// Key of the item that will be accessed public ValueType this[KeyType key] { get { return this.typedDictionary[key]; } } #region IDictionary<,> implementation /// Inserts an item into the Dictionary /// Key under which to add the new item /// Item that will be added to the Dictionary void IDictionary.Add(KeyType key, ValueType value) { throw new NotSupportedException( "Adding items is not supported by the read-only Dictionary" ); } /// Removes the item with the specified key from the Dictionary /// Key of the elementes that will be removed /// True if an item with the specified key was found and removed bool IDictionary.Remove(KeyType key) { throw new NotSupportedException( "Removing items is not supported by the read-only Dictionary" ); } /// Accesses an item in the Dictionary by its key /// Key of the item that will be accessed ValueType IDictionary.this[KeyType key] { get { return this.typedDictionary[key]; } set { throw new NotSupportedException( "Assigning items is not supported in a read-only Dictionary" ); } } #endregion #region IEnumerable implementation /// Returns a new object enumerator for the Dictionary /// The new object enumerator System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return (this.typedDictionary as IEnumerable).GetEnumerator(); } #endregion #region IDictionary implementation /// Removes all items from the Dictionary void IDictionary.Clear() { throw new NotSupportedException( "Clearing is not supported in a read-only Dictionary" ); } /// Adds an item into the Dictionary /// Key under which the item will be added /// Item that will be added void IDictionary.Add(object key, object value) { throw new NotSupportedException( "Adding items is not supported in a read-only Dictionary" ); } /// Determines whether the specified key exists in the Dictionary /// Key that will be checked for /// True if an item with the specified key exists in the Dictionary bool IDictionary.Contains(object key) { return this.objectDictionary.Contains(key); } /// Returns a new entry enumerator for the dictionary /// The new entry enumerator IDictionaryEnumerator IDictionary.GetEnumerator() { return this.objectDictionary.GetEnumerator(); } /// Whether the size of the Dictionary is fixed bool IDictionary.IsFixedSize { get { return this.objectDictionary.IsFixedSize; } } /// Returns a collection of all keys in the Dictionary ICollection IDictionary.Keys { get { if(this.readonlyKeyCollection == null) { this.readonlyKeyCollection = new ReadOnlyCollection( this.typedDictionary.Keys ); } return this.readonlyKeyCollection; } } /// Returns a collection of all values stored in the Dictionary ICollection IDictionary.Values { get { if(this.readonlyValueCollection == null) { this.readonlyValueCollection = new ReadOnlyCollection( this.typedDictionary.Values ); } return this.readonlyValueCollection; } } /// Removes an item from the Dictionary /// Key of the item that will be removed void IDictionary.Remove(object key) { throw new NotSupportedException( "Removing is not supported by the read-only Dictionary" ); } /// Accesses an item in the Dictionary by its key /// Key of the item that will be accessed /// The item with the specified key object IDictionary.this[object key] { get { return this.objectDictionary[key]; } set { throw new NotSupportedException( "Assigning items is not supported by the read-only Dictionary" ); } } #endregion #region ICollection<> implementation /// Inserts an already prepared element into the Dictionary /// Prepared element that will be added to the Dictionary void ICollection>.Add( KeyValuePair item ) { throw new NotSupportedException( "Adding items is not supported by the read-only Dictionary" ); } /// Removes all items from the Dictionary void ICollection>.Clear() { throw new NotSupportedException( "Clearing is not supported in a read-only Dictionary" ); } /// Removes all items from the Dictionary /// Item that will be removed from the Dictionary bool ICollection>.Remove( KeyValuePair itemToRemove ) { throw new NotSupportedException( "Removing items is not supported in a read-only Dictionary" ); } #endregion #region ICollection implementation /// Copies the contents of the Dictionary into an array /// Array the Dictionary contents will be copied into /// /// Starting index at which to begin filling the destination array /// void ICollection.CopyTo(Array array, int index) { this.objectDictionary.CopyTo(array, index); } /// Whether the Dictionary is synchronized for multi-threaded usage bool ICollection.IsSynchronized { get { return this.objectDictionary.IsSynchronized; } } /// Synchronization root on which the Dictionary locks object ICollection.SyncRoot { get { return this.objectDictionary.SyncRoot; } } #endregion #if !NO_SERIALIZATION #region ISerializable implementation /// Serializes the Dictionary /// /// Provides the container into which the Dictionary will serialize itself /// /// /// Contextual informations about the serialization environment /// void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { (this.typedDictionary as ISerializable).GetObjectData(info, context); } /// Called after all objects have been successfully deserialized /// Nicht unterstützt void IDeserializationCallback.OnDeserialization(object sender) { (this.typedDictionary as IDeserializationCallback).OnDeserialization(sender); } #endregion #endif //!NO_SERIALIZATION /// The wrapped Dictionary under its type-safe interface private IDictionary typedDictionary; /// The wrapped Dictionary under its object interface private IDictionary objectDictionary; /// ReadOnly wrapper for the keys collection of the Dictionary private ReadOnlyCollection readonlyKeyCollection; /// ReadOnly wrapper for the values collection of the Dictionary private ReadOnlyCollection readonlyValueCollection; } } // namespace Nuclex.Support.Collections