5

GitHubの誰かが、GitHubのプロジェクトのHashSetを比較する機能を求めています:https ://github.com/GregFinzer/Compare-Net-Objects/ 。タイプがハッシュセットであるかどうかを判断して、列挙子を取得できるようにする必要があります。何にキャストすればいいのかわかりません。これが私が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);
    }
}
4

4 に答える 4

4

ISet<T>の代わりに、、、ICollection<T>またはIEnumerable<T>汎用インターフェースで直接動作するだけで十分だと思いますHashSet<T>。これらのタイプは、次のアプローチを使用して検出できます。

// ...
    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());
    }
}
于 2012-04-17T05:00:10.033 に答える
1

ループしてGetInterfaces()IsGenericTypetrueとGetGenericTypeDefinition() == typeof(ISet<>)

于 2012-04-17T01:14:33.427 に答える
0

これはHashSetsに組み込まれています...メソッドSymmetricExceptWithを使用します。他にも組み込みの比較があります。参照: http: //msdn.microsoft.com/en-us/library/bb336848.aspx

于 2012-04-17T01:14:48.623 に答える
0

受け入れられた回答は、型や、場合によってはおよびDictionaryの他のサブクラスと区別されません。これはよりうまく機能します:ICollectionIEnumerable

Type t1 = typeof(HashSet<int>);
bool test1 = t1.IsGenericType && 
    t1.GetGenericTypeDefinition() == typeof(HashSet<>); // true

Type t2 = typeof(Dictionary<int, string>);
bool test2 = t2.IsGenericType && 
    t2.GetGenericTypeDefinition() == typeof(HashSet<>); // false

Type t3 = typeof(int);
bool test3 = t3.IsGenericType && 
    t3.GetGenericTypeDefinition() == typeof(HashSet<>); // false
于 2018-05-08T14:28:52.940 に答える