Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a SortedList readonly

I often have classes exposing lists as ReadOnlyCollection<T>s, i.e.

public class Class
{
  List<string> list;

  public ReadOnlyCollection<string> TheList
  {
    get { return list.AsReadOnly(); }
  }
}

What's the best way to do this for an IDictionary<T,U> such as a SortedList<string, string>?

like image 876
Matthew Finlay Avatar asked May 20 '11 01:05

Matthew Finlay


2 Answers

public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private readonly IDictionary<TKey, TValue> sourceDictionary;

    public ICollection<TKey> Keys
    {
        get { return sourceDictionary.Keys; }
    }

    public ICollection<TValue> Values
    {
        get { return sourceDictionary.Values; }
    }

    public TValue this[TKey key]
    {
        get { return sourceDictionary[key]; }
        set { throw new NotSupportedException(); }
    }

    public int Count
    {
        get { return sourceDictionary.Count; }
    }

    public bool IsReadOnly
    {
        get { return true; }
    }

    public ReadOnlyDictionary(IDictionary<TKey, TValue> sourceDictionary)
    {
        AssertUtilities.ArgumentNotNull(sourceDictionary, "sourceDictionary");

        this.sourceDictionary = sourceDictionary;
    }

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw new NotSupportedException();
    }

    public bool ContainsKey(TKey key)
    {
        return sourceDictionary.ContainsKey(key);
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw new NotSupportedException();
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return sourceDictionary.TryGetValue(key, out value);
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException();
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw new NotSupportedException();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        return sourceDictionary.Contains(item);
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        sourceDictionary.CopyTo(array, arrayIndex);
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException();
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return sourceDictionary.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)sourceDictionary).GetEnumerator();
    }
}

[Edit] @Simon Buchan and @Cory Nelson pointed out that it is better to use implicit interface implementation for those methods that are not supported. Updated the code accordingly.

like image 61
Alex Aza Avatar answered Sep 29 '22 03:09

Alex Aza


Create a ReadOnlyDictionary class that implements IDictionary as a wrapper around an internal Dictionary instance. For the methods that would modify the dictionary, throw an exception. Implement IsReadOnly to return true. Implement all other methods to pass through to the internal Dictionary instance.

like image 32
dthorpe Avatar answered Sep 29 '22 03:09

dthorpe