Mah*_*kia 11 .net c# dictionary hashset
我在C#中使用HashSetand Dictionary来实现Graph结构.HashSet当HashSet键是自定义类时,我遇到元素唯一性的问题.我在这里:
public class Point
{
public int x { get; set; }
public int y { get; set; }
}
public class Vertex
{
public Vertex(Point point)
{
VertexLabel = point;
}
public Point VertexLabel { get; private set; }
}
public class Edge
{
public Edge(Vertex to, Vertex from, double weight)
{
FromVertex = from;
ToVertex = to;
Weight = weight;
}
public Vertex FromVertex { get; private set; }
public Vertex ToVertex { get; private set; }
public double Weight { get; private set; }
}
public class Graph
{
public Graph()
{
_Vertexes = new HashSet<Vertex>();
_VertexEdgeMapping = new Dictionary<Vertex, LinkedList<Edge>>();
}
private HashSet<Vertex> _Vertexes;
private Dictionary<Vertex, LinkedList<Edge>> _VertexEdgeMapping;
}
Run Code Online (Sandbox Code Playgroud)
问题是当我有相同的顶点并且我想将它们添加到图形时,它们会被复制.如何定义一种HashSet能够理解顶点唯一性的方法?
Jon*_*eet 27
选项:
Equals和GetHashCode在Vertex(可能Point为简单起见),很可能实现IEquatable<T>,当您去IEqualityComparer<Vertex>并将其传递给.的构造函数HashSet<Vertex>第一个选项可能是最简单的,但我强烈建议您Point首先使用不可变类型:可变类型(或包含可变类型的类型)不能生成好的哈希键.我也许可以做到struct:
public struct Point : IEquatable<Point>
{
private readonly int x, y;
public int X { get { return x; } }
public int Y { get { return y; } }
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public override int GetHashCode()
{
return 31 * x + 17 * y; // Or something like that
}
public override bool Equals(object obj)
{
return obj is Point && Equals((Point) obj);
}
public bool Equals(Point p)
{
return x == p.x && y == p.y;
}
// TODO: Consider overloading the == and != operators
}
Run Code Online (Sandbox Code Playgroud)
......然后覆盖GetHashCode,并Equals贯彻IEquatable<>在Vertex太,如
// Note: sealed to avoid oddities around equality and inheritance
public sealed class Vertex : IEquatable<Vertex>
{
public Vertex(Point point)
{
VertexLabel = point;
}
public Point VertexLabel { get; private set; }
public override int GetHashCode()
{
return VertexLabel.GetHashCode();
}
public override bool Equals(object obj)
{
return Equals(obj as Vertex);
}
public bool Equals(Vertex vertex)
{
return vertex != null && vertex.VertexLabel.Equals(VertexLabel);
}
}
Run Code Online (Sandbox Code Playgroud)