Original
Since IReadOnlyList was added the parity between sets and lists has declined. It would be great to re-establish it.
Using it would be an implementation-agnostic way of saying: "here is this read-only collection where items are unique".
Clearly it's needed by many people:
SQL Server: https://msdn.microsoft.com/en-us/library/gg503096.aspx
Roslyn: https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/InternalUtilities/IReadOnlySet.cs
Some Guy In Comments: http://blogs.msdn.com/b/bclteam/archive/2013/03/06/update-to-immutable-collections.aspx
I found this discussion when working on a real world problem where I wanted to use the key collection of a dictionary for read only set operations. In order to support that case here's the API I propose.
Edit
Rationale
Proposed API
namespace System.Collections.Generic {
+ public interface IReadOnlySet<out T> : IReadOnlyCollection<T>, IEnumerable, IEnumerable<T> {+ bool Contains(T value);+ bool IsProperSubsetOf(IEnumerable<T> other);+ bool IsProperSupersetOf(IEnumerable<T> other);+ bool IsSubsetOf(IEnumerable<T> other);+ bool IsSupersetOf(IEnumerable<T> other);+ bool Overlaps(IEnumerable<T> other);+ bool SetEquals(IEnumerable<T> other);+ }- public class HashSet<T> : ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T> {+ public class HashSet<T> : ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T>, IReadOnlySet<T> {
}
- public class SortedSet<T> : ICollection, ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T> {+ public class SortedSet<T> : ICollection, ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T>, IReadOnlySet<T> {
}
+ public class ReadOnlySet<T> : ICollection<T>, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlySet<T>, ISet<T> {+ public int Count { get; }+ public ReadOnlySet(ISet<T> set);+ public bool Contains(T value);+ public bool IsProperSubsetOf(IEnumerable<T> other);+ public bool IsProperSupersetOf(IEnumerable<T> other);+ public bool IsSubsetOf(IEnumerable<T> other);+ public bool IsSupersetOf(IEnumerable<T> other);+ public bool Overlaps(IEnumerable<T> other);+ public bool SetEquals(IEnumerable<T> other);+ }
public class Dictionary<TKey, TValue> {
- public sealed class KeyCollection : ICollection, ICollection<TKey>, IEnumerable, IEnumerable<TKey>, IReadOnlyCollection<TKey> {+ public sealed class KeyCollection : ICollection, ICollection<TKey>, IEnumerable, IEnumerable<TKey>, IReadOnlyCollection<TKey>, IReadOnlySet<TKey> {+ public bool IsProperSubsetOf(IEnumerable<TKey> other);+ public bool IsProperSupersetOf(IEnumerable<TKey> other);+ public bool IsSubsetOf(IEnumerable<TKey> other);+ public bool IsSupersetOf(IEnumerable<TKey> other);+ public bool Overlaps(IEnumerable<TKey> other);+ public bool SetEquals(IEnumerable<TKey> other);
}
}
}Open Questions
- Is adding these methods to
Dictionary<TKey, TValue>.KeyCollection acceptable given the code size cost for a commonly instantiated generic type? See here. - Should
IReadOnlySet<T> be implemented in other DictionaryKeyCollections such as SortedDictionary or ImmutableDictionary?
Updates
- Removed
TryGetValue as it's not in ISet<T> and as such would prevent potentially ever rebasing ISet<T> to implement IReadOnlySet<T>. - Added
ReadOnlySet<T> class which is similar to ReadOnlyCollection<T>.
Original
Since
IReadOnlyListwas added the parity between sets and lists has declined. It would be great to re-establish it.Using it would be an implementation-agnostic way of saying: "here is this read-only collection where items are unique".
Clearly it's needed by many people:
SQL Server: https://msdn.microsoft.com/en-us/library/gg503096.aspx
Roslyn: https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/InternalUtilities/IReadOnlySet.cs
Some Guy In Comments: http://blogs.msdn.com/b/bclteam/archive/2013/03/06/update-to-immutable-collections.aspx
I found this discussion when working on a real world problem where I wanted to use the key collection of a dictionary for read only set operations. In order to support that case here's the API I propose.
Edit
Rationale
Proposed API
namespace System.Collections.Generic { + public interface IReadOnlySet<out T> : IReadOnlyCollection<T>, IEnumerable, IEnumerable<T> {+ bool Contains(T value);+ bool IsProperSubsetOf(IEnumerable<T> other);+ bool IsProperSupersetOf(IEnumerable<T> other);+ bool IsSubsetOf(IEnumerable<T> other);+ bool IsSupersetOf(IEnumerable<T> other);+ bool Overlaps(IEnumerable<T> other);+ bool SetEquals(IEnumerable<T> other);+ }- public class HashSet<T> : ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T> {+ public class HashSet<T> : ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T>, IReadOnlySet<T> { } - public class SortedSet<T> : ICollection, ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T> {+ public class SortedSet<T> : ICollection, ICollection<T>, IDeserializationCallback, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, ISerializable, ISet<T>, IReadOnlySet<T> { } + public class ReadOnlySet<T> : ICollection<T>, IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlySet<T>, ISet<T> {+ public int Count { get; }+ public ReadOnlySet(ISet<T> set);+ public bool Contains(T value);+ public bool IsProperSubsetOf(IEnumerable<T> other);+ public bool IsProperSupersetOf(IEnumerable<T> other);+ public bool IsSubsetOf(IEnumerable<T> other);+ public bool IsSupersetOf(IEnumerable<T> other);+ public bool Overlaps(IEnumerable<T> other);+ public bool SetEquals(IEnumerable<T> other);+ } public class Dictionary<TKey, TValue> { - public sealed class KeyCollection : ICollection, ICollection<TKey>, IEnumerable, IEnumerable<TKey>, IReadOnlyCollection<TKey> {+ public sealed class KeyCollection : ICollection, ICollection<TKey>, IEnumerable, IEnumerable<TKey>, IReadOnlyCollection<TKey>, IReadOnlySet<TKey> {+ public bool IsProperSubsetOf(IEnumerable<TKey> other);+ public bool IsProperSupersetOf(IEnumerable<TKey> other);+ public bool IsSubsetOf(IEnumerable<TKey> other);+ public bool IsSupersetOf(IEnumerable<TKey> other);+ public bool Overlaps(IEnumerable<TKey> other);+ public bool SetEquals(IEnumerable<TKey> other); } } }Open Questions
Dictionary<TKey, TValue>.KeyCollectionacceptable given the code size cost for a commonly instantiated generic type? See here.IReadOnlySet<T>be implemented in otherDictionaryKeyCollections such asSortedDictionaryorImmutableDictionary?Updates
TryGetValueas it's not inISet<T>and as such would prevent potentially ever rebasingISet<T>to implementIReadOnlySet<T>.ReadOnlySet<T>class which is similar toReadOnlyCollection<T>.