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

C#中判断购物车商品与历史订单商品是否存在交集的问题

问题:判断购物车商品是否存在于历史订单中

购物车中有若干商品,客户曾订购过其中某一件。已通过GetOrders()方法获取客户的历史订单列表,将购物车商品传入ProductFound方法,需判断购物车商品与订单中的OrderItems是否存在匹配。

原始错误代码及问题

最初编写的代码如下,已知存在匹配商品但始终返回false:

public bool ProductFound(IReadOnlyCollection<OrderItems> items)
{
    var orders = GetOrders();

    foreach (var order in orders)
    {
        if (items.Intersect(order.OrderItems).Any())
        {
            return true;
        }
    }

    return false;
}

尝试通过order.OrderItems.ProductId匹配ID时出现类型转换错误,修改为嵌套循环后仍未解决:

public bool ProductFound(IReadOnlyCollection<OrderItems> items)
{
    var orders = GetOrders();

    foreach (var order in orders)
    {
        foreach (var i in orders.OrderItems)
        {
            if (items.Contains(i))
            {
                return true;
            }
        }
    }

    return false;
}

问题原因分析

  1. Intersect/Contains失效原因:默认情况下,这些方法使用引用相等判断,只有当两个对象是内存中的同一实例时才会判定相等。即使两个OrderItems对象的ProductId相同,只要是不同实例,就会被判定为不相等。
  2. 嵌套循环的错误:代码中错误访问了orders.OrderItems,而不是当前遍历的order.OrderItems,导致逻辑错误。

正确实现方式

方式一:通过唯一标识(如ProductId)匹配(推荐)

无需修改OrderItems类,直接基于商品唯一ID判断,性能和可靠性都更高:

public bool ProductFound(IReadOnlyCollection<OrderItems> cartItems)
{
    var orders = GetOrders();
    // 提取购物车所有商品ID存入HashSet,提升查询效率
    var cartProductIds = cartItems.Select(item => item.ProductId).ToHashSet();

    foreach (var order in orders)
    {
        // 检查当前订单是否有商品ID存在于购物车ID集合中
        if (order.OrderItems.Any(orderItem => cartProductIds.Contains(orderItem.ProductId)))
        {
            return true;
        }
    }

    return false;
}

方式二:重写OrderItems的相等判断方法

如果需要基于对象内容进行相等判断,在OrderItems类中重写Equals和GetHashCode:

public class OrderItems
{
    public int ProductId { get; set; }
    // 其他属性...

    public override bool Equals(object obj)
    {
        // 先判断是否为同一类型实例
        if (!(obj is OrderItems otherItem))
            return false;
        // 基于ProductId判断相等
        return ProductId == otherItem.ProductId;
    }

    public override int GetHashCode()
    {
        // 基于ProductId生成哈希码
        return HashCode.Combine(ProductId);
    }
}

修改后,最初的Intersect代码即可正常工作:

public bool ProductFound(IReadOnlyCollection<OrderItems> items)
{
    var orders = GetOrders();

    foreach (var order in orders)
    {
        if (items.Intersect(order.OrderItems).Any())
        {
            return true;
        }
    }

    return false;
}

方式三:使用自定义相等比较器

若无法修改OrderItems类,可创建自定义比较器实现相等判断:

public class OrderItemEqualityComparer : IEqualityComparer<OrderItems>
{
    public bool Equals(OrderItems x, OrderItems y)
    {
        if (x == null || y == null)
            return x == y;
        return x.ProductId == y.ProductId;
    }

    public int GetHashCode(OrderItems obj)
    {
        return obj.ProductId.GetHashCode();
    }
}

在Intersect方法中传入该比较器即可:

public bool ProductFound(IReadOnlyCollection<OrderItems> items)
{
    var orders = GetOrders();
    var equalityComparer = new OrderItemEqualityComparer();

    foreach (var order in orders)
    {
        if (items.Intersect(order.OrderItems, equalityComparer).Any())
        {
            return true;
        }
    }

    return false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:03:24