You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套集合对象深度比较:如何实现MyClass列表的相等判断方法?

实现IReadOnlyList的逻辑相等判断方法

给定以下类定义:

public class MyClass
{
    public int[] BunchOfNumbers { get; set; }
    
    public int SomeOtherNumber { get; set; }
}

需要实现签名如下的相等性判断方法,要求仅当两个列表在逻辑上完全相等时返回true,需处理空值、数组null等复杂情况:

public bool AreItemsEqual(IReadOnlyList<MyClass> objA, IReadOnlyList<MyClass> objB)
{
    ...
}

简便实现方案

方案一:手动遍历比较(兼容性强,适用于所有.NET版本)

先编写辅助方法处理单个MyClass实例的相等判断,再遍历列表逐个比较:

  1. 单个MyClass实例的比较方法
private static bool AreMyClassEqual(MyClass a, MyClass b)
{
    // 引用直接相等或均为null
    if (ReferenceEquals(a, b)) return true;
    // 其中一个为null,另一个非null
    if (a is null || b is null) return false;
    // 比较值类型字段
    if (a.SomeOtherNumber != b.SomeOtherNumber) return false;
    // 比较数组:将null转换为空数组后,用SequenceEqual判断元素是否完全一致
    return Enumerable.SequenceEqual(a.BunchOfNumbers ?? Array.Empty<int>(), b.BunchOfNumbers ?? Array.Empty<int>());
}
  1. 列表相等判断方法
public bool AreItemsEqual(IReadOnlyList<MyClass> objA, IReadOnlyList<MyClass> objB)
{
    // 引用直接相等或均为null
    if (ReferenceEquals(objA, objB)) return true;
    // 其中一个为null,另一个非null
    if (objA is null || objB is null) return false;
    // 元素数量不同直接返回false
    if (objA.Count != objB.Count) return false;
    // 逐个比较每个元素
    for (int i = 0; i < objA.Count; i++)
    {
        if (!AreMyClassEqual(objA[i], objB[i]))
        {
            return false;
        }
    }
    return true;
}

方案二:使用IEqualityComparer+LINQ(代码更简洁)

将MyClass的相等逻辑封装为IEqualityComparer<MyClass>实现,再借助LINQ的SequenceEqual方法完成列表比较:

  1. 实现自定义相等比较器
public class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
    public bool Equals(MyClass x, MyClass y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (x is null || y is null) return false;
        if (x.SomeOtherNumber != y.SomeOtherNumber) return false;
        return Enumerable.SequenceEqual(x.BunchOfNumbers ?? Array.Empty<int>(), y.BunchOfNumbers ?? Array.Empty<int>());
    }

    public int GetHashCode(MyClass obj)
    {
        if (obj is null) return 0;
        // 计算哈希码,结合值字段和数组的结构哈希
        var arrayHash = obj.BunchOfNumbers?.Aggregate(0, (currentHash, num) => HashCode.Combine(currentHash, num)) ?? 0;
        return HashCode.Combine(obj.SomeOtherNumber, arrayHash);
    }
}
  1. 简化的列表相等判断方法
public bool AreItemsEqual(IReadOnlyList<MyClass> objA, IReadOnlyList<MyClass> objB)
{
    if (ReferenceEquals(objA, objB)) return true;
    if (objA is null || objB is null) return false;
    return objA.SequenceEqual(objB, new MyClassEqualityComparer());
}

关键注意点

  • 必须处理null场景:包括列表本身为null、列表中的MyClass实例为null、BunchOfNumbers数组为null的情况
  • 数组的相等判断需要用Enumerable.SequenceEqual,而非默认的引用比较
  • 哈希码的计算要与相等逻辑保持一致,避免使用数组默认的引用哈希(仅当需要用到哈希表等场景时需关注)

内容的提问来源于stack exchange,提问作者millie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:39:18