OrderedDictionary.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / CompMod / System / Collections / Specialized / OrderedDictionary.cs / 1305376 / OrderedDictionary.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Collections.Specialized { 
 
    using System;
    using System.Collections; 
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
 
    /// 
    ///  
    /// OrderedDictionary offers IDictionary syntax with ordering.  Objects 
    /// added or inserted in an IOrderedDictionary must have both a key and an index, and
    /// can be retrieved by either. 
    /// OrderedDictionary is used by the ParameterCollection because MSAccess relies on ordering of
    /// parameters, while almost all other DBs do not.  DataKeyArray also uses it so
    /// DataKeys can be retrieved by either their name or their index.
    /// 
    /// OrderedDictionary implements IDeserializationCallback because it needs to have the
    /// contained ArrayList and Hashtable deserialized before it tries to get its count and objects. 
    ///  
    /// 
    [Serializable] 
    public class OrderedDictionary : IOrderedDictionary, ISerializable, IDeserializationCallback {

        private ArrayList _objectsArray;
        private Hashtable _objectsTable; 
        private int _initialCapacity;
        private IEqualityComparer _comparer; 
        private bool _readOnly; 
        private Object _syncRoot;
        private SerializationInfo _siInfo; //A temporary variable which we need during deserialization. 

        private const string KeyComparerName = "KeyComparer";
        private const string ArrayListName = "ArrayList";
        private const string ReadOnlyName = "ReadOnly"; 
        private const string InitCapacityName = "InitialCapacity";
 
        public OrderedDictionary() : this(0) { 
        }
 
        public OrderedDictionary(int capacity) : this(capacity, null) {
        }

        public OrderedDictionary(IEqualityComparer comparer) : this(0, comparer) { 
        }
 
        public OrderedDictionary(int capacity, IEqualityComparer comparer) { 
            _initialCapacity = capacity;
            _comparer = comparer; 
        }

        private OrderedDictionary(OrderedDictionary dictionary) {
            if (dictionary == null) { 
                throw new ArgumentNullException("dictionary");
            } 
 
            _readOnly = true;
            _objectsArray = dictionary._objectsArray; 
            _objectsTable = dictionary._objectsTable;
            _comparer = dictionary._comparer;
            _initialCapacity = dictionary._initialCapacity;
        } 

        protected OrderedDictionary(SerializationInfo info, StreamingContext context) { 
            // We can't do anything with the keys and values until the entire graph has been deserialized 
            // and getting Counts and objects won't fail.  For the time being, we'll just cache this.
            // The graph is not valid until OnDeserialization has been called. 
            _siInfo = info;
        }

        ///  
        /// Gets the size of the table.
        ///  
        public int Count { 
            get {
                return objectsArray.Count; 
            }
        }

        ///  
        /// Indicates that the collection can grow.
        ///  
        bool IDictionary.IsFixedSize { 
            get {
                return _readOnly; 
            }
        }

        ///  
        /// Indicates that the collection is not read-only
        ///  
        public bool IsReadOnly { 
            get {
                return _readOnly; 
            }
        }

        ///  
        /// Indicates that this class is not synchronized
        ///  
        bool ICollection.IsSynchronized { 
            get {
                return false; 
            }
        }

        ///  
        /// Gets the collection of keys in the table in order.
        ///  
        public ICollection Keys { 
            get {
                return new OrderedDictionaryKeyValueCollection(objectsArray, true); 
            }
        }

        private ArrayList objectsArray { 
            get {
                if (_objectsArray == null) { 
                    _objectsArray = new ArrayList(_initialCapacity); 
                }
                return _objectsArray; 
            }
        }

        private Hashtable objectsTable { 
            get {
                if (_objectsTable == null) { 
                    _objectsTable = new Hashtable(_initialCapacity, _comparer); 
                }
                return _objectsTable; 
            }
        }

        ///  
        /// The SyncRoot object.  Not used because IsSynchronized is false
        ///  
        object ICollection.SyncRoot { 
            get {
                if (_syncRoot == null) { 
                    System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null);
                }
                return _syncRoot;
            } 
        }
 
        ///  
        /// Gets or sets the object at the specified index
        ///  
        public object this[int index] {
            get {
                return ((DictionaryEntry)objectsArray[index]).Value;
            } 
            set {
                if (_readOnly) { 
                    throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly)); 
                }
                if (index < 0 || index >= objectsArray.Count) { 
                    throw new ArgumentOutOfRangeException("index");
                }
                object key = ((DictionaryEntry)objectsArray[index]).Key;
                objectsArray[index] = new DictionaryEntry(key, value); 
                objectsTable[key] = value;
            } 
        } 

        ///  
        /// Gets or sets the object with the specified key
        /// 
        public object this[object key] {
            get { 
                return objectsTable[key];
            } 
            set { 
                if (_readOnly) {
                    throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly)); 
                }
                if (objectsTable.Contains(key)) {
                    objectsTable[key] = value;
                    objectsArray[IndexOfKey(key)] = new DictionaryEntry(key, value); 
                }
                else { 
                    Add(key, value); 
                }
            } 
        }

        /// 
        /// Returns an arrayList of the values in the table 
        /// 
        public ICollection Values { 
            get { 
                return new OrderedDictionaryKeyValueCollection(objectsArray, false);
            } 
        }

        /// 
        /// Adds a new entry to the table with the lowest-available index. 
        /// 
        public void Add(object key, object value) { 
            if (_readOnly) { 
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            } 
            objectsTable.Add(key, value);
            objectsArray.Add(new DictionaryEntry(key, value));
        }
 
        /// 
        /// Clears all elements in the table. 
        ///  
        public void Clear() {
            if (_readOnly) { 
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            }
            objectsTable.Clear();
            objectsArray.Clear(); 
        }
 
        ///  
        /// Returns a readonly OrderedDictionary for the given OrderedDictionary.
        ///  
        public OrderedDictionary AsReadOnly() {
            return new OrderedDictionary(this);
        }
 
        /// 
        /// Returns true if the key exists in the table, false otherwise. 
        ///  
        public bool Contains(object key) {
            return objectsTable.Contains(key); 
        }

        /// 
        /// Copies the table to an array.  This will not preserve order. 
        /// 
        public void CopyTo(Array array, int index) { 
            objectsTable.CopyTo(array, index); 
        }
 
        private int IndexOfKey(object key) {
            for (int i = 0; i < objectsArray.Count; i++) {
                object o = ((DictionaryEntry)objectsArray[i]).Key;
                if (_comparer != null) { 
                    if (_comparer.Equals(o, key)) {
                        return i; 
                    } 
                }
                else { 
                    if (o.Equals(key)) {
                        return i;
                    }
                } 
            }
            return -1; 
        } 

        ///  
        /// Inserts a new object at the given index with the given key.
        /// 
        public void Insert(int index, object key, object value) {
            if (_readOnly) { 
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            } 
            if (index > Count || index < 0) { 
                throw new ArgumentOutOfRangeException("index");
            } 
            objectsTable.Add(key, value);
            objectsArray.Insert(index, new DictionaryEntry(key, value));
        }
 
        /// 
        /// Handles the deserization event.  This method can be overridden. 
        ///  
        protected virtual void OnDeserialization(object sender) {
            if (_siInfo == null) { 
                throw new SerializationException(SR.GetString(SR.Serialization_InvalidOnDeser));
            }
            _comparer = (IEqualityComparer)_siInfo.GetValue(KeyComparerName, typeof(IEqualityComparer));
            _readOnly = _siInfo.GetBoolean(ReadOnlyName); 
            _initialCapacity = _siInfo.GetInt32(InitCapacityName);
 
            object[] serArray = (object[])_siInfo.GetValue(ArrayListName, typeof(object[])); 

            if (serArray != null) { 
                foreach (object o in serArray) {
                    DictionaryEntry entry;
                    try {
                        // DictionaryEntry is a value type, so it can only be casted. 
                        entry = (DictionaryEntry)o;
                    } 
                    catch { 
                        throw new SerializationException(SR.GetString(SR.OrderedDictionary_SerializationMismatch));
                    } 
                    objectsArray.Add(entry);
                    objectsTable.Add(entry.Key, entry.Value);
                }
            } 
        }
 
        ///  
        /// Removes the entry at the given index.
        ///  
        public void RemoveAt(int index) {
            if (_readOnly) {
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            } 
            if (index >= Count || index < 0) {
                throw new ArgumentOutOfRangeException("index"); 
            } 
            object key = ((DictionaryEntry)objectsArray[index]).Key;
            objectsArray.RemoveAt(index); 
            objectsTable.Remove(key);
        }

        ///  
        /// Removes the entry with the given key.
        ///  
        public void Remove(object key) { 
            if (_readOnly) {
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly)); 
            }
            if (key == null) {
                throw new ArgumentNullException("key");
            } 

            int index = IndexOfKey(key); 
            if (index < 0) { 
                return;
            } 

            objectsTable.Remove(key);
            objectsArray.RemoveAt(index);
        } 

        #region IDictionary implementation 
        ///  
        public virtual IDictionaryEnumerator GetEnumerator() {
            return new OrderedDictionaryEnumerator(objectsArray, OrderedDictionaryEnumerator.DictionaryEntry); 
        }
        #endregion

        #region IEnumerable implementation 
        /// 
        IEnumerator IEnumerable.GetEnumerator() { 
            return new OrderedDictionaryEnumerator(objectsArray, OrderedDictionaryEnumerator.DictionaryEntry); 
        }
        #endregion 

        #region ISerializable implementation
        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase",
                         Justification="mscorlib removed all link demands, so don't warn when overriding a method " + 
                                       "with no link demand.  Replace the LinkDemand with a SecurityCritical" +
                                       "annotation when the assembly is moved to the v4 security model.")] 
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] 		 
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
            if (info == null) { 
                throw new ArgumentNullException("info");
            }
            info.AddValue(KeyComparerName, _comparer, typeof(IEqualityComparer));
            info.AddValue(ReadOnlyName, _readOnly); 
            info.AddValue(InitCapacityName, _initialCapacity);
            object[] serArray = new object[Count]; 
            _objectsArray.CopyTo(serArray); 
            info.AddValue(ArrayListName, serArray);
        } 
        #endregion

        #region IDeserializationCallback implementation
        void IDeserializationCallback.OnDeserialization(object sender) { 
            OnDeserialization(sender);
        } 
        #endregion 

        ///  
        /// OrderedDictionaryEnumerator works just like any other IDictionaryEnumerator, but it retrieves DictionaryEntries
        /// in the order by index.
        /// 
        private class OrderedDictionaryEnumerator : IDictionaryEnumerator { 

            private int _objectReturnType; 
            internal const int Keys = 1; 
            internal const int Values = 2;
            internal const int DictionaryEntry = 3; 
            private IEnumerator arrayEnumerator;

            internal OrderedDictionaryEnumerator (ArrayList array, int objectReturnType) {
                arrayEnumerator = array.GetEnumerator(); 
                _objectReturnType = objectReturnType;
            } 
 
            /// 
            /// Retrieves the current DictionaryEntry.  This is the same as Entry, but not strongly-typed. 
            /// 
            public object Current {
                get {
                    if (_objectReturnType == Keys) { 
                        return ((DictionaryEntry)arrayEnumerator.Current).Key;
                    } 
                    if (_objectReturnType == Values) { 
                        return ((DictionaryEntry)arrayEnumerator.Current).Value;
                    } 
                    return Entry;
                }
            }
 
            /// 
            /// Retrieves the current DictionaryEntry 
            ///  
            public DictionaryEntry Entry {
                get { 
                    return new DictionaryEntry(((DictionaryEntry)arrayEnumerator.Current).Key, ((DictionaryEntry)arrayEnumerator.Current).Value);
                }
            }
 
            /// 
            /// Retrieves the key of the current DictionaryEntry 
            ///  
            public object Key {
                get { 
                    return ((DictionaryEntry)arrayEnumerator.Current).Key;
                }
            }
 
            /// 
            /// Retrieves the value of the current DictionaryEntry 
            ///  
            public object Value {
                get { 
                    return ((DictionaryEntry)arrayEnumerator.Current).Value;
                }
            }
 
            /// 
            /// Moves the enumerator pointer to the next member 
            ///  
            public bool MoveNext() {
                return arrayEnumerator.MoveNext(); 
            }

            /// 
            /// Resets the enumerator pointer to the beginning. 
            /// 
            public void Reset() { 
                arrayEnumerator.Reset(); 
            }
        } 

        /// 
        /// OrderedDictionaryKeyValueCollection implements a collection for the Values and Keys properties
        /// that is "live"- it will reflect changes to the OrderedDictionary on the collection made after the getter 
        /// was called.
        ///  
        private class OrderedDictionaryKeyValueCollection : ICollection { 
            private ArrayList _objects;
            bool isKeys; 

            public OrderedDictionaryKeyValueCollection(ArrayList array, bool isKeys) {
                this._objects = array;
                this.isKeys = isKeys; 
            }
 
            void ICollection.CopyTo(Array array, int index)  { 
                if (array==null)
                    throw new ArgumentNullException("array"); 
                if (index < 0)
                    throw new ArgumentOutOfRangeException("index");
                foreach (object o in _objects) {
                    array.SetValue(isKeys ? ((DictionaryEntry)o).Key : ((DictionaryEntry)o).Value, index); 
                    index++;
                } 
            } 

            int ICollection.Count { 
                get {
                    return _objects.Count;
                }
            } 

            bool ICollection.IsSynchronized { 
                get { 
                    return false;
                } 
            }

            object ICollection.SyncRoot {
                get { 
                    return _objects.SyncRoot;
                } 
            } 

            IEnumerator IEnumerable.GetEnumerator() { 
                return new OrderedDictionaryEnumerator(_objects, isKeys == true ? OrderedDictionaryEnumerator.Keys : OrderedDictionaryEnumerator.Values);
            }
        }
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Collections.Specialized { 
 
    using System;
    using System.Collections; 
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
 
    /// 
    ///  
    /// OrderedDictionary offers IDictionary syntax with ordering.  Objects 
    /// added or inserted in an IOrderedDictionary must have both a key and an index, and
    /// can be retrieved by either. 
    /// OrderedDictionary is used by the ParameterCollection because MSAccess relies on ordering of
    /// parameters, while almost all other DBs do not.  DataKeyArray also uses it so
    /// DataKeys can be retrieved by either their name or their index.
    /// 
    /// OrderedDictionary implements IDeserializationCallback because it needs to have the
    /// contained ArrayList and Hashtable deserialized before it tries to get its count and objects. 
    ///  
    /// 
    [Serializable] 
    public class OrderedDictionary : IOrderedDictionary, ISerializable, IDeserializationCallback {

        private ArrayList _objectsArray;
        private Hashtable _objectsTable; 
        private int _initialCapacity;
        private IEqualityComparer _comparer; 
        private bool _readOnly; 
        private Object _syncRoot;
        private SerializationInfo _siInfo; //A temporary variable which we need during deserialization. 

        private const string KeyComparerName = "KeyComparer";
        private const string ArrayListName = "ArrayList";
        private const string ReadOnlyName = "ReadOnly"; 
        private const string InitCapacityName = "InitialCapacity";
 
        public OrderedDictionary() : this(0) { 
        }
 
        public OrderedDictionary(int capacity) : this(capacity, null) {
        }

        public OrderedDictionary(IEqualityComparer comparer) : this(0, comparer) { 
        }
 
        public OrderedDictionary(int capacity, IEqualityComparer comparer) { 
            _initialCapacity = capacity;
            _comparer = comparer; 
        }

        private OrderedDictionary(OrderedDictionary dictionary) {
            if (dictionary == null) { 
                throw new ArgumentNullException("dictionary");
            } 
 
            _readOnly = true;
            _objectsArray = dictionary._objectsArray; 
            _objectsTable = dictionary._objectsTable;
            _comparer = dictionary._comparer;
            _initialCapacity = dictionary._initialCapacity;
        } 

        protected OrderedDictionary(SerializationInfo info, StreamingContext context) { 
            // We can't do anything with the keys and values until the entire graph has been deserialized 
            // and getting Counts and objects won't fail.  For the time being, we'll just cache this.
            // The graph is not valid until OnDeserialization has been called. 
            _siInfo = info;
        }

        ///  
        /// Gets the size of the table.
        ///  
        public int Count { 
            get {
                return objectsArray.Count; 
            }
        }

        ///  
        /// Indicates that the collection can grow.
        ///  
        bool IDictionary.IsFixedSize { 
            get {
                return _readOnly; 
            }
        }

        ///  
        /// Indicates that the collection is not read-only
        ///  
        public bool IsReadOnly { 
            get {
                return _readOnly; 
            }
        }

        ///  
        /// Indicates that this class is not synchronized
        ///  
        bool ICollection.IsSynchronized { 
            get {
                return false; 
            }
        }

        ///  
        /// Gets the collection of keys in the table in order.
        ///  
        public ICollection Keys { 
            get {
                return new OrderedDictionaryKeyValueCollection(objectsArray, true); 
            }
        }

        private ArrayList objectsArray { 
            get {
                if (_objectsArray == null) { 
                    _objectsArray = new ArrayList(_initialCapacity); 
                }
                return _objectsArray; 
            }
        }

        private Hashtable objectsTable { 
            get {
                if (_objectsTable == null) { 
                    _objectsTable = new Hashtable(_initialCapacity, _comparer); 
                }
                return _objectsTable; 
            }
        }

        ///  
        /// The SyncRoot object.  Not used because IsSynchronized is false
        ///  
        object ICollection.SyncRoot { 
            get {
                if (_syncRoot == null) { 
                    System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null);
                }
                return _syncRoot;
            } 
        }
 
        ///  
        /// Gets or sets the object at the specified index
        ///  
        public object this[int index] {
            get {
                return ((DictionaryEntry)objectsArray[index]).Value;
            } 
            set {
                if (_readOnly) { 
                    throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly)); 
                }
                if (index < 0 || index >= objectsArray.Count) { 
                    throw new ArgumentOutOfRangeException("index");
                }
                object key = ((DictionaryEntry)objectsArray[index]).Key;
                objectsArray[index] = new DictionaryEntry(key, value); 
                objectsTable[key] = value;
            } 
        } 

        ///  
        /// Gets or sets the object with the specified key
        /// 
        public object this[object key] {
            get { 
                return objectsTable[key];
            } 
            set { 
                if (_readOnly) {
                    throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly)); 
                }
                if (objectsTable.Contains(key)) {
                    objectsTable[key] = value;
                    objectsArray[IndexOfKey(key)] = new DictionaryEntry(key, value); 
                }
                else { 
                    Add(key, value); 
                }
            } 
        }

        /// 
        /// Returns an arrayList of the values in the table 
        /// 
        public ICollection Values { 
            get { 
                return new OrderedDictionaryKeyValueCollection(objectsArray, false);
            } 
        }

        /// 
        /// Adds a new entry to the table with the lowest-available index. 
        /// 
        public void Add(object key, object value) { 
            if (_readOnly) { 
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            } 
            objectsTable.Add(key, value);
            objectsArray.Add(new DictionaryEntry(key, value));
        }
 
        /// 
        /// Clears all elements in the table. 
        ///  
        public void Clear() {
            if (_readOnly) { 
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            }
            objectsTable.Clear();
            objectsArray.Clear(); 
        }
 
        ///  
        /// Returns a readonly OrderedDictionary for the given OrderedDictionary.
        ///  
        public OrderedDictionary AsReadOnly() {
            return new OrderedDictionary(this);
        }
 
        /// 
        /// Returns true if the key exists in the table, false otherwise. 
        ///  
        public bool Contains(object key) {
            return objectsTable.Contains(key); 
        }

        /// 
        /// Copies the table to an array.  This will not preserve order. 
        /// 
        public void CopyTo(Array array, int index) { 
            objectsTable.CopyTo(array, index); 
        }
 
        private int IndexOfKey(object key) {
            for (int i = 0; i < objectsArray.Count; i++) {
                object o = ((DictionaryEntry)objectsArray[i]).Key;
                if (_comparer != null) { 
                    if (_comparer.Equals(o, key)) {
                        return i; 
                    } 
                }
                else { 
                    if (o.Equals(key)) {
                        return i;
                    }
                } 
            }
            return -1; 
        } 

        ///  
        /// Inserts a new object at the given index with the given key.
        /// 
        public void Insert(int index, object key, object value) {
            if (_readOnly) { 
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            } 
            if (index > Count || index < 0) { 
                throw new ArgumentOutOfRangeException("index");
            } 
            objectsTable.Add(key, value);
            objectsArray.Insert(index, new DictionaryEntry(key, value));
        }
 
        /// 
        /// Handles the deserization event.  This method can be overridden. 
        ///  
        protected virtual void OnDeserialization(object sender) {
            if (_siInfo == null) { 
                throw new SerializationException(SR.GetString(SR.Serialization_InvalidOnDeser));
            }
            _comparer = (IEqualityComparer)_siInfo.GetValue(KeyComparerName, typeof(IEqualityComparer));
            _readOnly = _siInfo.GetBoolean(ReadOnlyName); 
            _initialCapacity = _siInfo.GetInt32(InitCapacityName);
 
            object[] serArray = (object[])_siInfo.GetValue(ArrayListName, typeof(object[])); 

            if (serArray != null) { 
                foreach (object o in serArray) {
                    DictionaryEntry entry;
                    try {
                        // DictionaryEntry is a value type, so it can only be casted. 
                        entry = (DictionaryEntry)o;
                    } 
                    catch { 
                        throw new SerializationException(SR.GetString(SR.OrderedDictionary_SerializationMismatch));
                    } 
                    objectsArray.Add(entry);
                    objectsTable.Add(entry.Key, entry.Value);
                }
            } 
        }
 
        ///  
        /// Removes the entry at the given index.
        ///  
        public void RemoveAt(int index) {
            if (_readOnly) {
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly));
            } 
            if (index >= Count || index < 0) {
                throw new ArgumentOutOfRangeException("index"); 
            } 
            object key = ((DictionaryEntry)objectsArray[index]).Key;
            objectsArray.RemoveAt(index); 
            objectsTable.Remove(key);
        }

        ///  
        /// Removes the entry with the given key.
        ///  
        public void Remove(object key) { 
            if (_readOnly) {
                throw new NotSupportedException(SR.GetString(SR.OrderedDictionary_ReadOnly)); 
            }
            if (key == null) {
                throw new ArgumentNullException("key");
            } 

            int index = IndexOfKey(key); 
            if (index < 0) { 
                return;
            } 

            objectsTable.Remove(key);
            objectsArray.RemoveAt(index);
        } 

        #region IDictionary implementation 
        ///  
        public virtual IDictionaryEnumerator GetEnumerator() {
            return new OrderedDictionaryEnumerator(objectsArray, OrderedDictionaryEnumerator.DictionaryEntry); 
        }
        #endregion

        #region IEnumerable implementation 
        /// 
        IEnumerator IEnumerable.GetEnumerator() { 
            return new OrderedDictionaryEnumerator(objectsArray, OrderedDictionaryEnumerator.DictionaryEntry); 
        }
        #endregion 

        #region ISerializable implementation
        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase",
                         Justification="mscorlib removed all link demands, so don't warn when overriding a method " + 
                                       "with no link demand.  Replace the LinkDemand with a SecurityCritical" +
                                       "annotation when the assembly is moved to the v4 security model.")] 
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] 		 
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
            if (info == null) { 
                throw new ArgumentNullException("info");
            }
            info.AddValue(KeyComparerName, _comparer, typeof(IEqualityComparer));
            info.AddValue(ReadOnlyName, _readOnly); 
            info.AddValue(InitCapacityName, _initialCapacity);
            object[] serArray = new object[Count]; 
            _objectsArray.CopyTo(serArray); 
            info.AddValue(ArrayListName, serArray);
        } 
        #endregion

        #region IDeserializationCallback implementation
        void IDeserializationCallback.OnDeserialization(object sender) { 
            OnDeserialization(sender);
        } 
        #endregion 

        ///  
        /// OrderedDictionaryEnumerator works just like any other IDictionaryEnumerator, but it retrieves DictionaryEntries
        /// in the order by index.
        /// 
        private class OrderedDictionaryEnumerator : IDictionaryEnumerator { 

            private int _objectReturnType; 
            internal const int Keys = 1; 
            internal const int Values = 2;
            internal const int DictionaryEntry = 3; 
            private IEnumerator arrayEnumerator;

            internal OrderedDictionaryEnumerator (ArrayList array, int objectReturnType) {
                arrayEnumerator = array.GetEnumerator(); 
                _objectReturnType = objectReturnType;
            } 
 
            /// 
            /// Retrieves the current DictionaryEntry.  This is the same as Entry, but not strongly-typed. 
            /// 
            public object Current {
                get {
                    if (_objectReturnType == Keys) { 
                        return ((DictionaryEntry)arrayEnumerator.Current).Key;
                    } 
                    if (_objectReturnType == Values) { 
                        return ((DictionaryEntry)arrayEnumerator.Current).Value;
                    } 
                    return Entry;
                }
            }
 
            /// 
            /// Retrieves the current DictionaryEntry 
            ///  
            public DictionaryEntry Entry {
                get { 
                    return new DictionaryEntry(((DictionaryEntry)arrayEnumerator.Current).Key, ((DictionaryEntry)arrayEnumerator.Current).Value);
                }
            }
 
            /// 
            /// Retrieves the key of the current DictionaryEntry 
            ///  
            public object Key {
                get { 
                    return ((DictionaryEntry)arrayEnumerator.Current).Key;
                }
            }
 
            /// 
            /// Retrieves the value of the current DictionaryEntry 
            ///  
            public object Value {
                get { 
                    return ((DictionaryEntry)arrayEnumerator.Current).Value;
                }
            }
 
            /// 
            /// Moves the enumerator pointer to the next member 
            ///  
            public bool MoveNext() {
                return arrayEnumerator.MoveNext(); 
            }

            /// 
            /// Resets the enumerator pointer to the beginning. 
            /// 
            public void Reset() { 
                arrayEnumerator.Reset(); 
            }
        } 

        /// 
        /// OrderedDictionaryKeyValueCollection implements a collection for the Values and Keys properties
        /// that is "live"- it will reflect changes to the OrderedDictionary on the collection made after the getter 
        /// was called.
        ///  
        private class OrderedDictionaryKeyValueCollection : ICollection { 
            private ArrayList _objects;
            bool isKeys; 

            public OrderedDictionaryKeyValueCollection(ArrayList array, bool isKeys) {
                this._objects = array;
                this.isKeys = isKeys; 
            }
 
            void ICollection.CopyTo(Array array, int index)  { 
                if (array==null)
                    throw new ArgumentNullException("array"); 
                if (index < 0)
                    throw new ArgumentOutOfRangeException("index");
                foreach (object o in _objects) {
                    array.SetValue(isKeys ? ((DictionaryEntry)o).Key : ((DictionaryEntry)o).Value, index); 
                    index++;
                } 
            } 

            int ICollection.Count { 
                get {
                    return _objects.Count;
                }
            } 

            bool ICollection.IsSynchronized { 
                get { 
                    return false;
                } 
            }

            object ICollection.SyncRoot {
                get { 
                    return _objects.SyncRoot;
                } 
            } 

            IEnumerator IEnumerable.GetEnumerator() { 
                return new OrderedDictionaryEnumerator(_objects, isKeys == true ? OrderedDictionaryEnumerator.Keys : OrderedDictionaryEnumerator.Values);
            }
        }
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK