C#中判断Product类对象相等时Contains与==返回false如何处理
问题根源
C#中引用类型的默认相等性比较逻辑是引用相等性比较,即默认判断两个对象是否指向堆上的同一块内存地址,而非判断对象的业务属性是否相等。只要两个Product是不同的实例,哪怕所有属性值完全一致,默认的Contains方法、==运算符都会返回false。
解决方法
方法1:重写Product类的Equals和GetHashCode方法,实现IEquatable接口(推荐)
这是最规范的实现方式,修改后的Product类示例如下(判断字段根据你实际的业务标识调整,比如商品ID、SKU等):
public class Product : IEquatable<Product> { // 示例业务属性,按实际需求修改 public int ProductId { get; set; } public string SKU { get; set; } public string ProductName { get; set; } // 实现IEquatable<Product>的强类型Equals方法 public bool Equals(Product other) { if (other == null) return false; // 按业务规则判断相等,这里用产品ID+SKU作为唯一标识 return ProductId == other.ProductId && SKU == other.SKU; } // 重写object基类的Equals方法 public override bool Equals(object obj) { return Equals(obj as Product); } // 必须同步重写GetHashCode,哈希类集合会先校验哈希值 public override int GetHashCode() { return HashCode.Combine(ProductId, SKU); } // 可选:重载==和!=运算符,满足直接用==判断相等的需求 public static bool operator ==(Product left, Product right) { if (left == null) { return right == null; } return left.Equals(right); } public static bool operator !=(Product left, Product right) { return !(left == right); } }
完成上述修改后,原有Storage代码中的Contains方法、prod1 == prod2判断都会自动使用你定义的业务相等规则,无需修改Storage代码即可正常提取共有产品。
方法2:不修改Product类,使用自定义相等比较器
如果Product类是第三方依赖,你无权修改源码,可以实现IEqualityComparer<Product>接口自定义比较逻辑:
public class ProductEqualityComparer : IEqualityComparer<Product> { public bool Equals(Product x, Product y) { if (x == null && y == null) return true; if (x == null || y == null) return false; return x.ProductId == y.ProductId && x.SKU == y.SKU; } public int GetHashCode(Product obj) { return HashCode.Combine(obj.ProductId, obj.SKU); } }
然后修改Storage中判断是否包含的逻辑,使用带比较器的重载方法:
if (b.many_product.Contains(prod, new ProductEqualityComparer()))
注意事项
- 相等性判断的字段必须选择业务上唯一标识产品的静态字段,不要把库存、售价等动态变化的属性加入判断逻辑
- 重写
Equals方法必须同步重写GetHashCode,否则会导致HashSet、Dictionary等哈希类集合操作出现不可预期的错误
额外提示:你提供的Storage代码存在两处可导致运行报错的问题:
many_product字段没有初始化,直接调用AddRange会触发空引用异常,建议修改为public List<Product> many_product = new List<Product>();- 你没有定义无参的Storage构造函数,
mutual_products方法中new Storage()会编译失败,需要补充无参构造函数。
内容的提问来源于stack exchange,提问作者Ruslan Mydruj
相关产品推荐
相关产品推荐

