📄 nameobjectcollectionbase.cs
字号:
/* * NameObjectCollectionBase.cs - Implementation of * "System.Collections.Specialized.NameObjectCollectionBase". * * Copyright (C) 2002 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */namespace System.Collections.Specialized{using System;using System.Globalization;using System.Collections;using System.Runtime.Serialization;#if !ECMA_COMPATpublic#elseinternal#endifabstract class NameObjectCollectionBase : ICollection, IEnumerable#if CONFIG_SERIALIZATION , ISerializable, IDeserializationCallback#endif{ // Internal state. We implement our own hash table rather than // use the Hashtable class, because we have to handle multiple // values per key, which Hashtable cannot do. Working around // Hashtable's foibles can give unreliable behaviour as entries // are added and removed. private Entry[] table; private IHashCodeProvider hcp; private IComparer cmp; private ArrayList entries; private bool readOnly; private const int HashTableSize = 61;#if CONFIG_SERIALIZATION private SerializationInfo info;#endif // Constructors. protected NameObjectCollectionBase() : this(0, null, null) {} protected NameObjectCollectionBase(int capacity) : this(capacity, null, null) {} protected NameObjectCollectionBase(IHashCodeProvider hashProvider, IComparer comparer) : this(0, hashProvider, comparer) {} protected NameObjectCollectionBase(int capacity, IHashCodeProvider hashProvider, IComparer comparer) { if(capacity < 0) { throw new ArgumentOutOfRangeException ("capacity", S._("ArgRange_NonNegative")); } if(hashProvider == null) { hashProvider = CaseInsensitiveHashCodeProvider.Default; } if(comparer == null) { comparer = CaseInsensitiveComparer.Default; } table = new Entry [HashTableSize]; hcp = hashProvider; cmp = comparer; entries = new ArrayList(capacity); readOnly = false; }#if CONFIG_SERIALIZATION protected NameObjectCollectionBase(SerializationInfo info, StreamingContext context) : this(0, null, null) { this.info = info; }#endif // Properties. public virtual KeysCollection Keys { get { return new KeysCollection(this); } } protected bool IsReadOnly { get { return readOnly; } set { readOnly = value; } } // Implement the ICollection interface. public virtual int Count { get { return entries.Count; } } void ICollection.CopyTo(Array array, int index) { foreach(Object obj in this) { array.SetValue(obj, index); ++index; } } bool ICollection.IsSynchronized { get { return false; } } Object ICollection.SyncRoot { get { return this; } } // Implement the IEnumerator interface. public IEnumerator GetEnumerator() { return new KeysEnumerator(this); }#if CONFIG_SERIALIZATION // Implement the ISerializable interface. public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { // Validate the parameters. if(info == null) { throw new ArgumentNullException("info"); } // Add general information. info.AddValue("ReadOnly", readOnly); info.AddValue("HashProvider", hcp, typeof(IHashCodeProvider)); info.AddValue("Comparer", cmp, typeof(IComparer)); info.AddValue("Count", entries.Count); // Build arrays for the keys and values and serialize them. String[] keys = new String [entries.Count]; Object[] values = new Object [entries.Count]; int posn; Entry entry; for(posn = 0; posn < entries.Count; ++posn) { entry = (Entry)(entries[posn]); keys[posn] = entry.key; values[posn] = entry.value; } info.AddValue("Keys", keys, typeof(String[])); info.AddValue("Values", values, typeof(Object[])); } // Implement the IDeserializationCallback interface. public virtual void OnDeserialization(Object sender) { // Bail out if we've already been deserialized. if(hcp != null) { return; } // Validate the deserialization state. if(info == null) { throw new SerializationException (S._("Serialize_StateMissing")); } // De-serialize the hash provider and comparer. hcp = (IHashCodeProvider)(info.GetValue ("HashProvider", typeof(IHashCodeProvider))); cmp = (IComparer)(info.GetValue ("Comparer", typeof(IComparer))); if(hcp == null || cmp == null) { throw new SerializationException (S._("Serialize_StateMissing")); } // De-serialize the key/value arrays. String[] keys = (String[])(info.GetValue ("Keys", typeof(String[]))); Object[] values = (String[])(info.GetValue ("Values", typeof(Object[]))); if(keys == null || values == null) { throw new SerializationException (S._("Serialize_StateMissing")); } int count = info.GetInt32("Count"); int posn; for(posn = 0; posn < count; ++posn) { BaseAdd(keys[posn], values[posn]); } // De-serialize the read-only flag last. readOnly = info.GetBoolean("ReadOnly"); // De-serialization is complete. info = null; }#endif // CONFIG_SERIALIZATION // Get the hash value for a string, restricted to the table size. private int GetHash(String name) { int hash = (name != null ? hcp.GetHashCode(name) : 0); return (int)(((uint)hash) % (uint)HashTableSize); } // Compare two keys for equality. private bool Compare(String key1, String key2) { if(key1 == null || key2 == null) { return (key1 == key2); } else { return (cmp.Compare(key1, key2) == 0); } } // Add a name/value pair to this collection. protected void BaseAdd(String name, Object value) { if(readOnly) { throw new NotSupportedException(S._("NotSupp_ReadOnly")); } Entry entry = new Entry(name, value); int hash = GetHash(name); Entry last = table[hash]; if(last == null) { table[hash] = entry; } else { while(last.next != null) { last = last.next; } last.next = entry; } entries.Add(entry); } // Clear this collection. protected void BaseClear() { if(readOnly) { throw new NotSupportedException(S._("NotSupp_ReadOnly")); } ((IList)table).Clear(); entries.Clear(); } // Get the item at a specific index within this collection. protected Object BaseGet(int index) { return ((Entry)(entries[index])).value; } // Get the item associated with a specific name within this collection. protected Object BaseGet(String name) { Entry entry = table[GetHash(name)]; while(entry != null) { if(Compare(entry.key, name)) { return entry.value; } entry = entry.next; } return null; } // Get a list of all keys in the collection. protected String[] BaseGetAllKeys() { String[] keys = new String [entries.Count]; int index = 0; foreach(Entry entry in entries) { keys[index++] = (String)(entry.key); } return keys; } // Get a list of all values in the collection. protected Object[] BaseGetAllValues() { Object[] values = new String [entries.Count]; int index = 0; foreach(Entry entry in entries) { values[index++] = entry.value; } return values; } // Get an array of a specific type of all values in the collection. protected Object[] BaseGetAllValues(Type type) { if(type == null) { throw new ArgumentNullException("type"); } Object[] values = (Object[]) Array.CreateInstance(type, entries.Count); int index = 0; foreach(Entry entry in entries) { values[index++] = entry.value; } return values; } // Get the key at a specific index. protected String BaseGetKey(int index)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -