我是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