gpt4 book ai didi

C# XNA : Trouble with Dictionaries

转载 作者:行者123 更新时间:2023-11-30 21:22:36 28 4
gpt4 key购买 nike

我是 C# 新手。也许我没有正确地实现 IEquatable,因为我的类型的对象应该被认为是相同的,但不是。

类(class):

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() 使用引用相等吗?我在 CompPoint 中的 Equals() 函数搞砸了吗?

这个函数也失败了:

    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);
}

测试失败并显示此消息:

Test method ShipAILabTest.BoardUtilsTest.dictCompPointTest threw exception: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

这个测试概括了我的期望。我希望由于 key 每次都相同,因此值将被覆盖。 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) 时则不会。为什么这适用于某些值(value)观而不适用于其他值(value)观?

更神秘的是:散列码函数似乎工作得相当糟糕。此测试失败:

    [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() 的调用有问题?

最佳答案

我认为Assert.AreEqual只使用 Object.Equals , 不是 IEquatable<T>.Equals .所以你需要覆盖 Equals反射(reflect)IEquatable<T>.Equals的逻辑.

或者您也可以使用 Assert.IsTrue :

IEquatable<CompPoint> p1 = new CompPoint(0, 0);
IEquatable<CompPoint> p2 = new CompPoint(0, 0);
Assert.IsTrue(p1.Equals(p2));

请注意,我将 p1 和 p2 声明为 IEquatable<CompPoint> : 这是为了确保 IEquatable<CompPoint>.Equals被称为而不是 Object.Equals , 因为接口(interface)是显式实现的

编辑:顺便说一下,您可能想要声明 CompPoint作为结构而不是类。这样,您甚至不必执行任何操作,因为值类型是根据它们的字段值进行比较的

关于C# XNA : Trouble with Dictionaries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2218816/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com