我是 C# 的新手。也许我没有IEquatable
正确实现,因为我的类型的对象应该被认为是相同的。
班上:
class CompPoint : IComparable {
public int X;
public int Y;
public CompPoint(int X, int Y) {
this.X = X;
this.Y = Y;
}
public override bool Equals(Object o) {
if (!(o is CompPoint)) {
throw new ArgumentException(String.Format("argument is not a CompPoint (%s given)", o));
}
CompPoint cp = (CompPoint)o;
return this.X == cp.X && this.Y == cp.Y;
}
public override int GetHashCode() {
int hash = base.GetHashCode(); // this is a problem. replace with a constant?
hash = (hash * 73) + this.X.GetHashCode();
hash = (hash * 73) + this.Y.GetHashCode();
return hash;
}
}
(除了这之外,还有更多的CompPoint
东西可以证明它是一个类。)
然后,此测试失败:
[TestMethod()]
public void compPointTest() {
Assert.AreEqual(new CompPoint(0, 0), new CompPoint(0, 0));
}
我有什么误解?是否Assert.AreEqual()
使用参照平等?我的Equals()
功能有问题CompPoint
吗?
此功能也失败:
public void EqualsTest() {
Assert.IsTrue(new CompPoint(1, 1).Equals(new CompPoint(1, 1)));
}
这样做的原因是我正在使用 a Dictionary
,并且它没有按照我希望的方式工作:
[TestMethod()]
public void dictCompPointTest() {
IDictionary<CompPoint, int> dict = new Dictionary<CompPoint, int>();
dict[new CompPoint(0, 0)] = 4;
dict[new CompPoint(0, 0)] = 24;
dict[new CompPoint(0, 0)] = 31;
Assert.AreEqual(31, dict[new CompPoint(0, 0)]);
Assert.AreEqual(1, dict.Count);
}
测试失败并显示以下消息:
测试方法 ShipAILabTest.BoardUtilsTest.dictCompPointTest 抛出异常:System.Collections.Generic.KeyNotFoundException:字典中不存在给定的键。
这个测试概括了我的期望。我希望由于密钥每次都相同,因此该值将被覆盖。Dictionary
测试相等性的用途是什么?
更新:根据 Thomas 的建议,我添加了一个相等函数,现在CompPoint
比较测试有效,并且dictCompPointTest
有效。
public override bool Equals(Object o) {
if (!(o is CompPoint)) {
throw new ArgumentException(String.Format("argument is not a CompPoint (%s given)", o));
}
CompPoint cp = (CompPoint)o;
return this.X == cp.X && this.Y == cp.Y;
}
奇怪的是,这个测试仍然失败:
[TestMethod()]
public void dictCPTest2() {
IDictionary<CompPoint, int> dict = new Dictionary<CompPoint, int>();
dict[new CompPoint(2, 2)] = 2;
dict[new CompPoint(2, 2)] = 2;
Assert.AreEqual(1, dict.Count);
}
当键是时测试也会失败,但当键是new CompPoint(4, 1)
时不会new CompPoint(0, 1)
。为什么这可能适用于某些价值观而不适用于其他价值观?
更神秘的是:哈希码函数似乎工作得很糟糕。此测试失败:
[TestMethod()]
public void hashCodeTest() {
int x = 0;
int y = 0;
Assert.AreEqual(new CompPoint(x, y).GetHashCode(), new CompPoint(x, y).GetHashCode());
}
上面列出了哈希码函数。这里有什么问题?这两个CompPoint
对象不应该具有相同的哈希码吗?也许我的电话base.getHashCode()
有问题?