You can create your own comparable read-only collection.
public class ComparableReadOnlyCollection<T> : ReadOnlyCollection<T>
{
public ComparableReadOnlyCollection(IList<T> list)
: base(list.ToArray())
{
}
public override bool Equals(object other)
{
return
other is IEnumerable<T> otherEnumerable &&
otherEnumerable.SequenceEqual(this);
}
public override int GetHashCode()
{
int hash = 43;
unchecked {
foreach (T item in this) {
hash = 19 * hash + item.GetHashCode();
}
}
return hash;
}
}
Note that ReadOnlyCollection<T>
is just a wrapper for the original list. If you modify this list, the ReadOnlyCollection<T>
reflects those changes. My implementation copies the original list to an array to make it really immutable.
But be aware that if the elements T
are of a reference type, you can still modify members of the original objects! So be careful.
This test works as expected:
var hashSet = new HashSet<ComparableReadOnlyCollection<int>>();
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 1, 7 }));
Console.WriteLine(hashSet.Contains(new ComparableReadOnlyCollection<int>(new [] { 1, 7 })));
Console.WriteLine(hashSet.Contains(new ComparableReadOnlyCollection<int>(new [] { 7, 1 })));
Console.WriteLine(hashSet.Contains(new ComparableReadOnlyCollection<int>(new [] { 1, 7, 0 })));
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 1, 7 }));
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 1, 7, 0 }));
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 7, 1 }));
Console.WriteLine(hashSet.Count);
Console.ReadKey();
It prints
True
False
False
3
Note that it does not print 4, as there cannot be duplicates in the set.
2nd solution:
After reading your edit, I am not sure what you really want. Did you mean to create a HashSet<int>
instead of a HashSet<List<int>>
and to compare the elements of the lists instead of the lists themselves?
HashSet<int> _hash = new HashSet<int>(new List<int> { 1, 1, 2, 3, 5, 8, 13 });
Now the hash set contains the numbers { 1, 2, 3, 5, 8, 13 }. Set elements are always unique.
You can then test
var hash2 = new HashSet<int> { 3, 8 };
if (_hash.IsSupersetOf(hash2)) {
Console.WriteLine("_hash contains 3 and 8");
}
or, what is equivalent:
if (hash2.IsSubsetOf(_hash)) {
Console.WriteLine("_hash contains 3 and 8");
}
3rd solution:
What about a List<HashSet<int>>
? Because now, you can apply set operations to each element of the list (which is a hash set).
> is not the right data structure. Tell us more about your use case. What are you trying to achieve?
– Gerardo Grignoli Nov 09 '19 at 16:58> and I want to make sure that each element List is unique inside List
– Lost Nov 09 '19 at 19:23>
> or HashSet> too. You can use my answer with what you want. https://stackoverflow.com/questions/150750/hashset-vs-list-performance
– Nov 09 '19 at 21:10