我是C#的新手。也许我没有正确实施IEquatable
,因为我认为应该被认为是相同的对象不是。C#XNA:字典故障
类:
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)));
}
这种情况的原因是,我使用的是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
用于测试平等?
更新:我添加了一个平等的功能,按托马斯的建议,现在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;
}
令人不解,这个测试仍然失败:在密钥new CompPoint(4, 1)
[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(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()
是个问题?
这很吸引人,但最终没有成效。 'Dictionary'仍然无法检测到重复项。 – 2010-02-08 00:36:20
我觉得'getHashCode()'可能会导致问题。 (见上) – 2010-02-08 00:43:18
不知道你是否修复了这个问题,但是如果你的GetHashCode方法仍然是你在上面的代码中发布的,它仍然会为两个实例生成一个不同的对象(即两个新的CompPoint(0, 0))由于他们调用base.GetHashCode() – jeffora 2010-02-08 00:55:18