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

C#求两个不同自定义列表交集失败,Equals方法未触发求助

问题原因及修复方案

你的代码存在几个核心问题,导致Intersect返回空集合且Equals方法从未触发:

1. 未重写GetHashCode方法

LINQ的Intersect内部依赖哈希表实现,会优先比较对象的哈希码。如果两个对象哈希码不同,根本不会调用Equals方法。你仅实现了IEquatable<CompareObject>的Equals,但未重写GetHashCode,默认哈希码基于对象引用生成,即使compareString相同,不同对象的哈希码也不一致,导致无法匹配交集。

2. 子类构造函数未复用父类逻辑

CompareObjectA和CompareObjectB的构造函数直接赋值字段,未调用父类构造函数,既不符合面向对象设计原则,也容易因重复代码引入错误。

3. Equals方法未处理null及类型差异

当前Equals方法若other为null,直接访问other.compareString会抛出空引用异常,同时未处理子类类型不同的情况(虽然你已将对象转为CompareObject,但规范上需做校验)。


修复后的完整代码

internal class CompareObject : IEquatable<CompareObject>
{
    public CompareObject(object myParentObject, string compareString) 
    {
        this.myParentObject = myParentObject;
        this.compareString = compareString;
    }

    public string compareString { get; set; }
    public object myParentObject { get; set; }

    public bool Equals(CompareObject? other)
    {
        if (other is null) return false;
        // 确保类型一致(若允许子类跨类型比较可移除此判断)
        if (GetType() != other.GetType()) return false;
        return string.Equals(this.compareString, other.compareString, StringComparison.Ordinal);
    }

    // 重写Object.Equals保证逻辑一致性
    public override bool Equals(object? obj)
    {
        return Equals(obj as CompareObject);
    }

    // 基于比较字段生成哈希码
    public override int GetHashCode()
    {
        return compareString?.GetHashCode(StringComparison.Ordinal) ?? 0;
    }
}

internal class CompareObjectA : CompareObject
{
    public CompareObjectA(customClassA myParentObject)
        : base(myParentObject, myParentObject.customCompareField)
    {
    }
}

internal class CompareObjectB : CompareObject
{
    public CompareObjectB(customClassB myParentObject)
        : base(myParentObject, myParentObject.customCompareField)
    {
    }
}

public void Execute()
{
    var listA = new List<CompareObjectA>(<<SAMPLE VALUES>>);
    var listB = new List<CompareObjectB>(<<SAMPLE VALUES>>);

    // 用Cast更简洁地转换类型
    var listC = listA.Cast<CompareObject>().Intersect(listB.Cast<CompareObject>()).ToList();
}

额外说明

  • 使用string.Equals并指定StringComparison,可避免文化差异导致的比较错误,可根据需求选择OrdinalIgnoreCase(忽略大小写)等枚举值。
  • 重写Object.Equals是为了保证通过object类型比较时逻辑一致,避免出现矛盾结果。

内容的提问来源于stack exchange,提问作者Christoffel de Gruyter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:31:34