Я новичок в 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.dictCo mpPointTest исключение: System.Collections.Generic.KeyNotFoundException: Данный ключ отсутствует в словаре .
Этот тест инкапсулирует мои ожидания. Я надеюсь, что, поскольку ключ идентичен каждый раз, значение будет перезаписано. Что такое Dictionary
, чтобы проверить равенство?
UPDATE: Я добавил функцию равенства, согласно предложению Томаса, и теперь 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()
является проблемой?
Это интригующе, но в конечном счете бесплодно. «Словарь» по-прежнему не может обнаружить дубликаты. –
Я думаю, что 'getHashCode()' может вызвать проблему. (см. выше) –
Не знаете, исправлено это или нет, но если ваш метод GetHashCode по-прежнему является тем, что вы разместили в приведенном выше коде, он все равно будет генерировать другое для двух экземпляров (то есть два новых CompPoint (0, 0)) из-за их вызова base.GetHashCode() – jeffora