如何使用自定义对象作为字典键?

时间:2018-07-21 13:55:51

标签: c#

我想创建一个Dictionary<Coordinate, Status>,但是密钥始终等于"Bot.Core.Games.Coordinate"

坐标

public class Coordinate
{
    public int x { get; set; }
    public int y { get; set; }
}

状态

public class Enums
{
    public enum Status { UNCAPTURED, PLAYER1, PLAYER2, WIN }
}

第一次尝试

Dictionary<Coordinate, Status> Fields { get; set; } = new Dictionary<Coordinate, Status>()
{
    {new Coordinate() { x = 0, y = 0 }, Status.UNCAPTURED}
}

第二次尝试

我做了一些研究,结果发现:Use custom object as Dictionary Key
所以代码现在看起来像这样:

public class Coordinate
{
    public int x { get; set; }
    public int y { get; set; }

    public bool Equals(Coordinate coordinate) => coordinate.x.Equals(x) && coordinate.y.Equals(y);
    public bool Equals(object o) => Equals(o as Coordinate);
    public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode();
}

第三次尝试

由于以前没有尝试过的代码都能正常工作,因此我进行了更多研究并发现了this
所以现在的代码是:

public class Coordinate
{
    public int x { get; set; }
    public int y { get; set; }

    public class CoordinateEqualityComparer : IEqualityComparer<Coordinate>
    {
        public bool Equals(Coordinate a, Coordinate b) => ((a.x == b.x) & (a.y == b.y));

        public int GetHashCode(Coordinate obj)
        {
            string combined = obj.x + "|" + obj.y;
            return (combined.GetHashCode());
        }
    }
}

Dictionary<Coordinate, Status> Fields { get; set; } = new Dictionary<Coordinate, Status>(new Coordinate.CoordinateEqualityComparer())
{
     {new Coordinate() { x = 0, y = 0 }, Status.UNCAPTURED}
}

密钥始终为"Bot.Core.Games.Coordinate"。该如何解决?

2 个答案:

答案 0 :(得分:2)

您在第二次尝试中没有覆盖:

public override bool Equals(object o)

enter image description here

答案 1 :(得分:1)

键始终显示为Bot.Core.Games.Coordinate,因为默认情况下,ToString方法返回类名,这是调试器调用以显示其值的方法。如果您重写这样的方法:

public override string ToString() => $"{x} / {y}";

它将显示其真实值。

您第三次尝试的问题是(根据Camilo Terevinto和ZorgoZ的指出)您的平等比较-尝试

public override bool Equals(Coordinate a, Coordinate b)
{
    return ((a.x == b.x) && (a.y == b.y));
}

代替