BLOG.CSHARPHELPER.COM: Make a Set class that inherits from HashSet and that support operators such as union and intersection in C#
Make a Set class that inherits from HashSet and that support operators such as union and intersection in C#
The example Use the HashSet class to represent sets and perform set operations in C# explains how to use the HashSet class to represent and manipulate sets. Unfortunately to manipulate the sets you need to use methods such as IntersectWith, UnionWith, and SymmetricExceptWith instead of more intuitive operators such as &, |, and ^.
This example shows how to override those operators to make set operations easier.
To override these operators, you need to add code to the class. You might like to add code by using the partial keyword but that only works if every piece of the class uses the keyword and Microsoft's HashSet class doesn't use that keyword. In other words, you cannot add code to an existing class.
To work around this problem, this example derives a Set class that inherits from HashSet. This also lets me use the slightly more intuitive class name Set.
The following code shows the complete Set class.
class Set<T> : HashSet<T> { // Constructors. public Set() : base() { } public Set(IEnumerable<T> enumerable) : base(enumerable) { } public Set(IEqualityComparer<T> comparer) : base(comparer) { } public Set(IEnumerable<T> enumerable, IEqualityComparer<T> comparer) : base(enumerable, comparer) { }
// Union. public static Set<T> operator |(Set<T> A, Set<T> { Set<T> result = new Set<T>(A); result.UnionWith(; return result; }
// Intersection. public static Set<T> operator &(Set<T> A, Set<T> { Set<T> result = new Set<T>(A); result.IntersectWith(; return result; }
// Xor. public static Set<T> operator ^(Set<T> A, Set<T> { Set<T> result = new Set<T>(A); result.SymmetricExceptWith(; return result; }
// Subset. public static bool operator <(Set<T> A, Set<T> { return A.IsSubsetOf(; }
// Superset. public static bool operator >(Set<T> A, Set<T> { return A.IsSupersetOf(; }
// Contains element. public static bool operator >(Set<T> A, T element) { return A.Contains(element); }
// Consists of a single element. public static bool operator <(Set<T> A, T element) { return (A > element) && (A.Count == 1); } }
The class starts with constructors that simply invoke the base class's constructors. These are needed so the main program can create a Set and so the operators can create new Sets.
The binary (two operand) union, intersection, and XOR operators copy the first operand and then use the appropriate HashSet method to combine the copy with the second set.
The subset and superset operators simply invoke the HashSet class's IsSubsetOf and IsSupersetOf methods.
The "contains element" and "equals element" operators determine whether the set contains an element and whether it contains only the element. I would probably omit the second of these but the operators come in pairs so if you override the > operator then you must also override the < operator. (Alternatively you could have < throw an exception.)
Comments