|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionHave you ever needed the capabilities provided by the BackgroundThe whole thing started when I was writing a custom configuration
component. I originally stored the configuration information in a
The problem I ran into was that the Unfortunately, portions of my application expected the configuration information to be sequential, I quickly learned the SortedList was not the tool for the job I was trying to do. After spending several hours looking for a data structure to fit my
needs in
The I finally bit the bullet and wrote the Design/ImplementationThe I just took an Here is the declaration of the class: public abstract class Hashlist : IDictionary, IEnumerable { //array list that contains all the keys //as they are inserted, the index is associated with //a key so when pulling out values by index //we can get the key for the index, pull from the //hashtable the proper value with the corresponding //key //This is basically the same as a sorted list but //does not sort the items, rather it leaves them in the //order they were inserted - like a list protected ArrayList m_oKeys = new ArrayList(); protected Hashtable m_oValues = new Hashtable(); Now here is the #region ICollection implementation
//ICollection implementation
public int Count
{
get{return m_oValues.Count;}
}
public bool IsSynchronized
{
get{return m_oValues.IsSynchronized;}
}
public object SyncRoot
{
get{return m_oValues.SyncRoot;}
}
public void CopyTo(System.Array oArray, int iArrayIndex)
{
m_oValues.CopyTo(oArray, iArrayIndex);
}
#endregion
Next is the One important note here is that if you notice the Therefore, when you want an item by index, just get the key from the
#region IDictionary implementation
//IDictionary implementation
public void Add(object oKey, object oValue)
{
m_oKeys.Add(oKey);
m_oValues.Add(oKey, oValue);
}
public bool IsFixedSize
{
get{return m_oKeys.IsFixedSize;}
}
public bool IsReadOnly
{
get{return m_oKeys.IsReadOnly;}
}
public ICollection Keys
{
get{return m_oValues.Keys;}
}
public void Clear()
{
m_oValues.Clear();
m_oKeys.Clear();
}
public bool Contains(object oKey)
{
return m_oValues.Contains(oKey);
}
public bool ContainsKey(object oKey)
{
return m_oValues.ContainsKey(oKey);
}
public IDictionaryEnumerator GetEnumerator()
{
return m_oValues.GetEnumerator();
}
public void Remove(object oKey)
{
m_oValues.Remove(oKey);
m_oKeys.Remove(oKey);
}
public object this[object oKey]
{
get{return m_oValues[oKey];}
set{m_oValues[oKey] = value;}
}
public ICollection Values
{
get{return m_oValues.Values;}
}
#endregion
Now for the trick of getting this #region IEnumerable implementation
IEnumerator IEnumerable.GetEnumerator()
{
return m_oValues.GetEnumerator();
}
#endregion
But wait... didn't I just implement a foreach(MyObject o in MyHashlist)
{
.... blah blah ....
}
can only be used if you implement the foreach(IDictionaryEntry o in MyHashlist)
{
.... blah blah ....
}
IEnumerator IEnumerable.GetEnumerator()
#region Hashlist specialized implementation
//specialized indexer routines
public object this[string Key]
{
get{return m_oValues[Key];}
}
public object this[int Index]
{
get{return m_oValues[m_oKeys[Index]];}
}
#endregion
Notice that the indexors are overloaded to take an index or a key string.
This makes this data structure really handy. Also you may ask about the
Using the HashlistSo you may ask yourself... what good is all this code if I can't use it?
Right you are, so here are some examples of what you could do: public class SectionList : Hashlist
{
public new Section this[string Key]
{
get{return (Section)base[Key];}
}
public new Section this[int Index]
{
get
{
object oTemp = base[Index];
return (Section)oTemp;
}
}
public SectionList()
{
}
}
In the above code I created a specialized list that returns a Section class
from the indexors. As you can see, implmenting your own specialized lists that
have all the functionality of both Points of InterestOne interesting tid bit of information that I did learn is that: Using an enumeration with a This is because: The key/value pair capability of Thanks to Guy Swartwout for pointing out strange behavior in my config component that forced this issue to the surface. I sure did learn alot about .NET collections. History
|
||||||||||||||||||||||