You can use the following decorator to wrap the hash set and return an ICollection<T>
that is read-only (the IsReadOnly
property returns true and modification methods throw a NotSupportedException
as specified in the contract of ICollection<T>
):
public class MyReadOnlyCollection<T> : ICollection<T>
{
private readonly ICollection<T> decoratedCollection;
public MyReadOnlyCollection(ICollection<T> decorated_collection)
{
decoratedCollection = decorated_collection;
}
public IEnumerator<T> GetEnumerator()
{
return decoratedCollection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) decoratedCollection).GetEnumerator();
}
public void Add(T item)
{
throw new NotSupportedException();
}
public void Clear()
{
throw new NotSupportedException();
}
public bool Contains(T item)
{
return decoratedCollection.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
decoratedCollection.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
throw new NotSupportedException();
}
public int Count
{
get { return decoratedCollection.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
}
And you can use it like this:
public class MyClass
{
private readonly HashSet<string> _referencedColumns;
public ICollection<string> ReferencedColumns {
get { return new MyReadOnlyCollection<string>(_referencedColumns); }
}
//...
Please note that this solution will not take a snapshot of the HashSet, instead it will hold a reference to the HashSet. This means that the returned collection will contain a live version of the HashSet, i.e., if the HashSet is changed, the consumer that obtained the read only collection before the change would be able to see the change.