首页 > 解决方案 > 通用比较功能

问题描述

我正在尝试创建一个通用比较函数来查看一个类的两个实例是否可能包含一个 List<> 的成员变量。

bool IsEqual<T>(T a, T b)
{
    var props = typeof(T).GetProperties();
    foreach(var property in props)
    {
        var aVal = property.GetValue(a);
        var bVal = property.GetValue(b);
        if (aVal as System.Collections.IEnumerable != null)
        {
        // Convert into lists, do something with SequenceEqual and possibly recursive call to IsEqual
        }

        if (!Equals(aVal,bVal)) return false;
    }
    return true;
}

我不确定如何将给定的成员变量转换为正确的列表,因此我可以对其执行 SequenceEqual 来比较列表。

我将在 IsEqual() 中使用的类不是我的程序本机的,而是来自 DLL。

标签: c#

解决方案


以下代码对您有用吗?

public static bool DeepEquals(object a, object b)
{
    if (a == null)
    {
        if (b == null) return true;
        else return false;
    }
    else if (b == null) return false;

    if (object.ReferenceEquals(a, b)) return true;

    var comparable = a as IComparable;
    if (comparable != null)
    {
        return comparable.CompareTo(b) == 0;
    }

    var aType = a.GetType();
    var bType = b.GetType();
    if (aType != bType) return false;

    var aEnumerable = a as IEnumerable;
    if (aEnumerable != null)
    {
        var bEnumerable = (IEnumerable)b;
        var aEnumerator = aEnumerable.GetEnumerator();
        var bEnumerator = bEnumerable.GetEnumerator();
        while (true)
        {
            var amoved = aEnumerator.MoveNext();
            var bmoved = bEnumerator.MoveNext();
            if (amoved != bmoved) return false;
            if (amoved == false && bmoved == false) return true;
            if (DeepEquals(aEnumerator.Current, bEnumerator.Current) == false) return false;
        }
    }

    var props = aType.GetProperties();
    foreach (var prop in props)
    {
        if (DeepEquals(prop.GetValue(a), prop.GetValue(b)) == false) return false;
    }
    return true;
}

请注意,此方法不是通用的。实现泛型方法更加困难,因为您在运行时不知道属性的类型,也不知道集合项的类型。


推荐阅读