我有两个自定义类,ChangeRequest
和 ChangeRequests
,其中一个 ChangeRequests
可以包含很多 ChangeRequest
实例。
public class ChangeRequests : IXmlSerializable, ICloneable, IEnumerable<ChangeRequest>,
IEquatable<ChangeRequests> { ... }
public class ChangeRequest : ICloneable, IXmlSerializable, IEquatable<ChangeRequest>
{ ... }
我正在尝试做两个的并集 ChangeRequests
实例。但是,似乎没有删除重复项。我的MSTest单元测试如下:
var cr1 = new ChangeRequest { CRID = "12" };
var crs1 = new ChangeRequests { cr1 };
var crs2 = new ChangeRequests
{
cr1.Clone(),
new ChangeRequest { CRID = "34" }
};
Assert.AreEqual(crs1[0], crs2[0], "First CR in both ChangeRequests should be equal");
var unionedCRs = new ChangeRequests(crs1.Union<ChangeRequest>(crs2));
ChangeRequests expected = crs2.Clone();
Assert.AreEqual(expected, unionedCRs, "Duplicates should be removed from a Union");
最后一行测试失败,unionedCRs
包含 cr1
的两个副本.当我尝试调试并逐步执行每一行时,我在 ChangeRequest.Equals(object)
中有一个断点在第一行,以及ChangeRequest.Equals(ChangeRequest)
的第一行,但都没有被击中。为什么联合包含重复的 ChangeRequest
实例?
编辑:按要求,这里是ChangeRequests.Equals(ChangeRequests)
:
public bool Equals(ChangeRequests other)
{
if (ReferenceEquals(this, other))
{
return true;
}
return null != other && this.SequenceEqual<ChangeRequest>(other);
}
这里是 ChangeRequests.Equals(object)
:
public override bool Equals(object obj)
{
return Equals(obj as ChangeRequests);
}
编辑:我覆盖了GetHashCode
在两个ChangeRequest
和 ChangeRequests
但仍在我的测试中,如果我这样做 IEnumerable<ChangeRequest> unionedCRsIEnum = crs1.Union<ChangeRequest>(crs2);
, unionedCRsIEnum
最终得到了 ChangeRequest
的两个副本与 CRID
12.
编辑: 我的 Equals
有问题或 GetHashCode
在某处实现,因为 Assert.AreEqual(expected, unionedCRs.Distinct(), "Distinct should remove duplicates");
失败,expected
的字符串表示和 unionedCRs.Distinct()
表明unionedCRs.Distinct()
肯定有两份 CR 12。
最佳答案
确保您的 GetHashCode
实现与您的 Equals
一致 - Enumerable.Union
方法似乎同时使用了两者。
如果你实现了一个而不是另一个,你应该从编译器得到警告;您仍然需要确保这两种方法相互一致。这是规则的方便摘要:Why is it important to override GetHashCode when Equals method is overridden?
关于c# - 合并两个自定义类返回重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3134000/