Area di riferimento
 - Developing applications that use system types and collections
    - Manage a group of associated data in a .NET Framework application by using collections. (Refer System.Collections namespace)
        - DictionaryBase class  
    DictionaryBase class
 La classe astratta DictionaryBase fornisce un punto di partenza per l'implementazione di dizionari fortemente tipizzati.
Ecco come è definita:
  [Serializable, ComVisible(true)]
public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable
{
    // Fields
    private Hashtable hashtable;    // Utilizza un Hashtable al suo interno  
    // Methods
    protected DictionaryBase();
    public void Clear();
    public void CopyTo(Array array, int index);
    public IDictionaryEnumerator GetEnumerator();
    protected virtual void OnClear();
    protected virtual void OnClearComplete();
    protected virtual object OnGet(object key, object currentValue);
    protected virtual void OnInsert(object key, object value);
    protected virtual void OnInsertComplete(object key, object value);
    protected virtual void OnRemove(object key, object value);
    protected virtual void OnRemoveComplete(object key, object value);
    protected virtual void OnSet(object key, object oldValue, object newValue);
    protected virtual void OnSetComplete(object key, object oldValue, object newValue);
    protected virtual void OnValidate(object key, object value);
    void IDictionary.Add(object key, object value);
    bool IDictionary.Contains(object key);
    void IDictionary.Remove(object key);
    IEnumerator IEnumerable.GetEnumerator();  
    // Properties
    public int Count { get; }
    protected IDictionary Dictionary { get; }
    protected Hashtable InnerHashtable { get; }
    bool ICollection.IsSynchronized { get; }
    object ICollection.SyncRoot { get; }
    bool IDictionary.IsFixedSize { get; }
    bool IDictionary.IsReadOnly { get; }
    object IDictionary.this[object key] { get; set; }
    ICollection IDictionary.Keys { get; }
    ICollection IDictionary.Values { get; }
}
 
Prelevando un esempio dal sito msdn http://msdn2.microsoft.com/en-us/library/system.collections.dictionarybase.aspx vediamo ome potrebbe essere implementata una classe che rappresenta un dizionario di stringhe che però non possono essere più lunghe di 5 caratteri.
  public class ShortStringDictionary : DictionaryBase
{  
    public String this[String key]
    {
        get
        {
            return ((String)Dictionary[key]);
        }
        set
        {
            Dictionary[key] = value;
        }
    }  
    public ICollection Keys
    {
        get
        {
            return (Dictionary.Keys);
        }
    }  
    public ICollection Values
    {
        get
        {
            return (Dictionary.Values);
        }
    }  
    public void Add(String key, String value)
    {
        Dictionary.Add(key, value);
    }  
    public bool Contains(String key)
    {
        return (Dictionary.Contains(key));
    }  
    public void Remove(String key)
    {
        Dictionary.Remove(key);
    }  
    protected override void OnInsert(Object key, Object value)
    {
        if (key.GetType() != typeof(System.String))
            throw new ArgumentException("key must be of type String.", "key");
        else
        {
            String strKey = (String)key;
            if (strKey.Length > 5)
                throw new ArgumentException("key must be no more than 5 characters in length.", "key");
        }  
        if (value.GetType() != typeof(System.String))
            throw new ArgumentException("value must be of type String.", "value");
        else
        {
            String strValue = (String)value;
            if (strValue.Length > 5)
                throw new ArgumentException("value must be no more than 5 characters in length.", "value");
        }
    }  
    protected override void OnRemove(Object key, Object value)
    {
        if (key.GetType() != typeof(System.String))
            throw new ArgumentException("key must be of type String.", "key");
        else
        {
            String strKey = (String)key;
            if (strKey.Length > 5)
                throw new ArgumentException("key must be no more than 5 characters in length.", "key");
        }
    }  
    protected override void OnSet(Object key, Object oldValue, Object newValue)
    {
        if (key.GetType() != typeof(System.String))
            throw new ArgumentException("key must be of type String.", "key");
        else
        {
            String strKey = (String)key;
            if (strKey.Length > 5)
                throw new ArgumentException("key must be no more than 5 characters in length.", "key");
        }  
        if (newValue.GetType() != typeof(System.String))
            throw new ArgumentException("newValue must be of type String.", "newValue");
        else
        {
            String strValue = (String)newValue;
            if (strValue.Length > 5)
                throw new ArgumentException("newValue must be no more than 5 characters in length.", "newValue");
        }
    }  
    protected override void OnValidate(Object key, Object value)
    {
        if (key.GetType() != typeof(System.String))
            throw new ArgumentException("key must be of type String.", "key");
        else
        {
            String strKey = (String)key;
            if (strKey.Length > 5)
                throw new ArgumentException("key must be no more than 5 characters in length.", "key");
        }  
        if (value.GetType() != typeof(System.String))
            throw new ArgumentException("value must be of type String.", "value");
        else
        {
            String strValue = (String)value;
            if (strValue.Length > 5)
                throw new ArgumentException("value must be no more than 5 characters in length.", "value");
        }
    }  
}
 
Vedremo in seguito come i generics possono risolvere in modo brillante il problema della creazione di classi fortemente tipizzate.