How to determine if a type is of type HashSet and how to cast it?

.net, c#

Solution

I believe it is enough works directly with the `ISet<T>`, the `ICollection<T>` or the `IEnumerable<T>` generic interfaces instead of the `HashSet<T>`. You can detect these types using the following approach:

// ...
    Type t = typeof(HashSet<int>);
    bool test1 = GenericClassifier.IsICollection(t); // true
    bool test2 = GenericClassifier.IsIEnumerable(t); // true
    bool test3 = GenericClassifier.IsISet(t); // true
}
//
public static class GenericClassifier {
    public static bool IsICollection(Type type) {
        return Array.Exists(type.GetInterfaces(), IsGenericCollectionType);
    }
    public static bool IsIEnumerable(Type type) {
        return Array.Exists(type.GetInterfaces(), IsGenericEnumerableType);
    }
    public static bool IsISet(Type type) {
        return Array.Exists(type.GetInterfaces(), IsGenericSetType);
    }
    static bool IsGenericCollectionType(Type type) {
        return type.IsGenericType && (typeof(ICollection<>) == type.GetGenericTypeDefinition());
    }
    static bool IsGenericEnumerableType(Type type) {
        return type.IsGenericType && (typeof(IEnumerable<>) == type.GetGenericTypeDefinition());
    }
    static bool IsGenericSetType(Type type) {
        return type.IsGenericType && (typeof(ISet<>) == type.GetGenericTypeDefinition());
    }
}

Problem

I have someone on GitHub asking for the ability to compare HashSets for my project on GitHub: https://github.com/GregFinzer/Compare-Net-Objects/. I need to be able to determine if a type is a hash set and then get the enumerator. I am not sure what to cast it to. Here is what I have for an IList: ``` private bool IsIList(Type type) { return (typeof(IList).IsAssignableFrom(type)); } private void CompareIList(object object1, object object2, string breadCrumb) { IList ilist1 = object1 as IList; IList ilist2 = object2 as IList; if (ilist1 == null) //This should never happen, null check happens one level up throw new ArgumentNullException("object1"); if (ilist2 == null) //This should never happen, null check happens one level up throw new ArgumentNullException("object2"); try { _parents.Add(object1); _parents.Add(object2); //Objects must be the same length if (ilist1.Count != ilist2.Count) { Differences.Add(string.Format("object1{0}.Count != object2{0}.Count ({1},{2})", breadCrumb, ilist1.Count, ilist2.Count)); if (Differences.Count >= MaxDifferences) return; } IEnumerator enumerator1 = ilist1.GetEnumerator(); IEnumerator enumerator2 = ilist2.GetEnumerator(); int count = 0; while (enumerator1.MoveNext() && enumerator2.MoveNext()) { string currentBreadCrumb = AddBreadCrumb(breadCrumb, string.Empty, string.Empty, count); Compare(enumerator1.Current, enumerator2.Current, currentBreadCrumb); if (Differences.Count >= MaxDifferences) return; count++; } } finally { _parents.Remove(object1); _parents.Remove(object2); } } ```

Original source