Recipe 5.11. Creating a Dictionary with Max and Min Value Boundaries Problem You need to use a generic Dictionary object in your project that stores only numeric data in its value (the key can be of any type)between a set maximum and minimum value. Solution Create a class with accessors and methods that enforce these boundaries. The class shown in Example 5-4, MaxMinValueDictionary, allows only integers that fall between a maximum and minimum value to be stored. Example 5-4. Creating a dictionary with max and min value boundaries using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; [Serializable] public class MaxMinValueDictionary<T> { protected Dictionary<T,int> internalDictionary = null; public MaxMinValueDictionary(int minValue, int maxValue) { this.minValue = minValue; this.maxValue = maxValue; internalDictionary = new Dictionary<T,int>( ); } protected int minValue = int.MinValue; protected int maxValue = int.MaxValue; public int Count { get { return (internalDictionary.Count); } } public Dictionary<T,int>.KeyCollection Keys { get { return (internalDictionary.Keys); } } public Dictionary<T,int>.ValueCollection Values { get { return (internalDictionary.Values); } } public int this[T key] { get { return (internalDictionary[key]); } set { if (value >= minValue && value <= maxValue) { internalDictionary[key] = value; } else { throw (new ArgumentOutOfRangeException("value", value, "Value must be within the range " + minValue + " to " + maxValue)); } } } public void Add(T key, int value) { if (value >= minValue && value <= maxValue) { internalDictionary.Add(key, value); } else { throw (new ArgumentOutOfRangeException("value", value, "Value must be within the range " + minValue + " to " + maxValue)); } } public bool ContainsKey(T key) { return (internalDictionary.ContainsKey(key)); } public bool ContainsValue(int value) { return (internalDictionary.ContainsValue(value)); } public override bool Equals(object obj) { return (internalDictionary.Equals(obj)); } public IEnumerator GetEnumerator( ) { return (internalDictionary.GetEnumerator( )); } public override int GetHashCode( ) { return (internalDictionary.GetHashCode( )); } public void GetObjectData(SerializationInfo info, StreamingContext context) { internalDictionary.GetObjectData(info, context); } public void OnDeserialization (object sender) { internalDictionary.OnDeserialization(sender); } public override string ToString( ) { return (internalDictionary.ToString( )); } public bool TryGetValue(T key, out int value) { return (internalDictionary.TryGetValue(key, out value)); } public void Remove(T key) { internalDictionary.Remove(key); } public void Clear( ) { internalDictionary.Clear( ); } } | Discussion The MaxMinValueDictionary class wraps the Dictionary<T,U> class so it can restrict the range of allowed values. The overloaded constructor for the MaxMinValueDictionary class is defined here: public MaxMinValueDictionary(int minValue, int maxValue) This constructor allows the range of values to be set. Its parameters are:
minValue -
The smallest integer value that can be added as a value in a key/value pair
maxValue -
The largest integer value that can be added as a value in a key/value pair The overridden indexer has both get and set. The get returns the value that matches the provided key. The set checks the value parameter to determine whether it is within the boundaries of the minValue and maxValue fields before it is set. The Add method accepts an integer for its value parameter and performs the same tests as the set accessor on the indexer. If the test passes, the integer is added to the MaxMinValueDictionary. To modify the MaxMinValueDictionary<T> class to accept numeric values other than an integer, simply change all instances of the int value parameter to another numeric type, such as a double or a long. Anytime you see Dictionary<T,int>, you will need to change the int type to the numeric type of your choosing. In addition, the minValue and maxValue fields will need to be changed to that type, as will the parameters to the constructor and the return type of the indexer. See Also See the "Hashtable Class" topic in the MSDN documentation. |