C#列表比较忽略类项
Posted
技术标签:
【中文标题】C#列表比较忽略类项【英文标题】:C# List comparison ignoring class item 【发布时间】:2015-04-16 12:25:43 【问题描述】:我有两个数据库 DB1 和 DB2,我从每个数据库中检索销售订单并放入列表中。我现在想在 DB2 中找到 DB1 中缺少的销售订单,以便将它们添加到 DB2 中
我有listDB1
和ListDB2
的形式:
public class SalesOrder
public int docNum;
public string cardCode;
public string cardName;
public DateTime docDate;
public DateTime docDueDate;
public double docTotal;
public int lineItemCount;
public string comments;
我现在想比较两个列表,忽略两个列表的 docNum
,这是在比较其余元素时自动生成的。使用:
unaddedSOs = listDB1.Except(listDB2).ToList();
比较包括 docNum 在内的所有内容。如何实现我需要的,以便获得未添加的文档编号?
【问题讨论】:
尝试实现IEquatable<SalesOrder>
。
"比较所有,包括 docNum",不,它只是默认比较引用。覆盖Equals
+ GetHashCode
或提供自定义IEqualityComparer<SalesOrder>
。
@TimSchmelter:确实,我根本看不出原始版本是如何工作的,除非这两个列表包含相同项目的相同引用。
@Codor:它不会仍然比较字符串成员的引用吗?
@Baldrick 尽管string
是一种引用类型,但它是通过值语义实现的,即检查是否相等并比较内容。
【参考方案1】:
您可以实现IEquatable<SalesOrder>
,或创建自定义IEqualityComparer<SalesOrder>
。请注意,我还建议您将这些公共字段转换为属性。
public class SalesOrder : IEquatable<SalesOrder>
public int DocNum get; set;
public string CardCode get; set;
public string CardName get; set;
public DateTime DocDate get; set;
public DateTime DocDueDate get; set;
public double DocTotal get; set;
public int LineItemCount get; set;
public string Comments get; set;
public bool Equals(SalesOrder other)
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(cardCode, other.cardCode) &&
string.Equals(cardName, other.cardName) &&
docDueDate.Equals(other.docDueDate) &&
docTotal.Equals(other.docTotal) &&
lineItemCount == other.lineItemCount &&
string.Equals(comments, other.comments);
public override bool Equals(object obj)
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((SalesOrder) obj);
public override int GetHashCode()
unchecked
var hashCode = (cardCode != null ? cardCode.GetHashCode() : 0);
hashCode = (hashCode*397) ^ (cardName != null ? cardName.GetHashCode() : 0);
hashCode = (hashCode*397) ^ docDueDate.GetHashCode();
hashCode = (hashCode*397) ^ docTotal.GetHashCode();
hashCode = (hashCode*397) ^ lineItemCount;
hashCode = (hashCode*397) ^ (comments != null ? comments.GetHashCode() : 0);
return hashCode;
【讨论】:
当我们在做这件事时,这个Blog article 处理了一个有争议的,但令人惊讶的优雅和灵活的技术,用于自定义实现IEquatable
。
@Codor 那篇文章谈论的是IComparable
,而不是IEquatable
。 They're not the same.
确实,我弄错了。不过我相信这种方法可以推广。以上是关于C#列表比较忽略类项的主要内容,如果未能解决你的问题,请参考以下文章