An Elegant Way to Implement ReadOnlyDictionary(TKey, TValue) in C#
While working on creating an application framework for a personal project, I needed a way to expose a Dictionary<TKey, TValue> object from one of my methods. The only caveat being, I wanted the Dictionary object to be read-only.
I knew that there exists a ReadOnlyCollection<T> in the FCL, but to my dismay there is no built-n way of creating a read-only Dictionary in .NET. I searched the web to see how other people are solving this problem, but didn’t find a suitable implementation that I was happy with. Hence I created a nice little ReadOnlyDictionary<TKey, TValue> that essentially allows developers to expose an immutable Dictionary object of specified key and value types.
public sealed class ReadOnlyDictionary < TKey, TValue > : ReadOnlyCollection < KeyValuePair < TKey, TValue > >
{
public ReadOnlyDictionary(IDictionary<tkey , TValue> items)
: base(items.ToList()) { }
public TValue this[TKey key]
{
get
{
var valueQuery = GetQuery(key);
if (valueQuery.Count() == 0)
throw new NullReferenceException("No value found for given key");
return valueQuery.First().Value;
}
}
public bool ContainsKey(TKey key)
{
return (GetQuery(key).Count() > 0);
}
public bool TryGetValue(TKey key, out TValue value)
{
var toReturn = ContainsKey(key);
value = toReturn ? this[key] : default(TValue);
return toReturn;
}
private IEnumerable < KeyValuePair < TKey, TValue > > GetQuery(TKey key)
{
return (from t in base.Items where t.Key.Equals(key) select t);
}
}
As you can see the class itself is very concise. This is because it cleverly derives from ReadOnlyCollection<KeyValuePair<TKey, TValue>>, and only adds two methods and an indexer. Also it uses LINQ to Objects to select Dictionary items, and the LINQ query is neatly tucked in a private method where it’s re-used from other public methods.
