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

如何在C#中正确比较Street与StandardStreet复杂对象

判断Street与StandardStreet相等的最优实现

需求说明

当Street的名称等于StandardStreet的名称,或是StandardStreet的任意同义词名称时,判定两者相等,同时要保证Contains方法能正常工作(Contains依赖对象的Equals实现)。

现有代码问题

  1. 强制将obj转换为Street,传入其他BaseStreet子类会抛出异常
  2. BaseStreet无CityId属性,属于代码笔误
  3. 未重写GetHashCode,导致集合类(如HashSet、List)的Contains无法正确工作(哈希码不匹配会直接判定不相等)
  4. 类型判断过于严格(obj.GetType() != typeof(BaseStreet)),子类实例传入会直接返回false

正确实现方案

1. 修正StandardStreet的Equals与GetHashCode

public class StandardStreet : BaseStreet
{
    public HashSet<SynonymStreet> SynonymStreets { get; set; } = new HashSet<SynonymStreet>();

    public override bool Equals(object? obj)
    {
        // 空值直接返回false
        if (obj is null) return false;
        // 引用相同直接判定相等
        if (ReferenceEquals(this, obj)) return true;
        // 非BaseStreet子类直接返回false
        if (obj is not BaseStreet otherStreet) return false;
        
        // 处理Street类型的匹配逻辑
        if (obj is Street street)
        {
            // 匹配自身名称或同义词名称,可根据业务调整大小写规则
            return Name.Equals(street.Name, StringComparison.OrdinalIgnoreCase) 
                || SynonymStreets.Any(s => s.Name.Equals(street.Name, StringComparison.OrdinalIgnoreCase));
        }
        
        // 处理StandardStreet自身的相等判断
        if (obj is StandardStreet standardStreet)
        {
            return Id == standardStreet.Id || Name.Equals(standardStreet.Name, StringComparison.OrdinalIgnoreCase);
        }
        
        // 其他BaseStreet子类默认按名称判断
        return Name.Equals(otherStreet.Name, StringComparison.OrdinalIgnoreCase);
    }

    public override int GetHashCode()
    {
        // 基于名称生成哈希码,保证相等对象的哈希码一致,大小写规则与Equals保持一致
        return Name?.GetHashCode(StringComparison.OrdinalIgnoreCase) ?? 0;
    }
}

2. 可选:实现Street的反向相等判断

如果需要支持Street.Equals(StandardStreet)的对称判断,在Street类中重写Equals:

public class Street : BaseStreet
{
    public override bool Equals(object? obj)
    {
        if (obj is null) return false;
        if (ReferenceEquals(this, obj)) return true;
        // 调用StandardStreet的Equals逻辑,保证对称性
        if (obj is StandardStreet standardStreet)
        {
            return standardStreet.Equals(this);
        }
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return Name?.GetHashCode(StringComparison.OrdinalIgnoreCase) ?? 0;
    }
}

3. 使用Contains示例

// 构造StandardStreet集合
var standardStreets = new List<StandardStreet>
{
    new StandardStreet
    {
        Name = "中山路",
        SynonymStreets = new HashSet<SynonymStreet>
        {
            new SynonymStreet { Name = "中山大道" }
        }
    }
};

// 待匹配的Street
var targetStreet = new Street { Name = "中山大道" };

// 使用Contains判断是否匹配
bool isMatched = standardStreets.Contains(targetStreet); // 返回true

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:40:34