C# - 定义自定义按键的HashSet [英] C# - defining hashset with custom key

查看:139
本文介绍了C# - 定义自定义按键的HashSet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是HashSet的词典在C#来实现图形结构。我与HashSet的元素的唯一一个问题,当HashSet的关键是定制类。在这里,我有:

I am using the HashSet and Dictionary in C# to implement a Graph structure. I have a problem with the uniqueness of hashset elements when the hashset key is a customized class. Here I have:

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

现在的问题是,当我有相同的顶点,我想将它们添加到图中,他们得到复制。我怎么可以定义HashSet中会明白我的顶点独特的方式?

The problem is that when I have same vertexes and I want to add them to the graph, they get duplicated. how can I define a way that the HashSet would understand the uniqueness of my vertexes?

推荐答案

选项:

  • 覆盖等于 GetHash code 顶点(也许为简单起见),很可能实施 [IEquatable] [1]; T&GT; 作为你去
  • 创建你自己的实施的IEqualityComparer&LT;点&GT; ,并传递到构造函数中的HashSet&LT;点&GT;
  • Override Equals and GetHashCode in Vertex (and probably Point for simplicity), quite possibly implement [IEquatable][1]<T> as you go
  • Create your own implementation of IEqualityComparer<Vertex> and pass that to the constructor of the HashSet<Vertex>

第一种选择可能是最简单的,但我的强烈的建议您不可改变第一:可变类型(或类型包含可变类型)不好好哈希键。我可能会使其成为一个结构,也:

The first option is likely to be the simplest, but I would strongly recommend that you make Point immutable first: mutable types (or types containing mutable types) don't make good hash keys. I'd probably make it a struct, too:

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
}

...然后覆盖 GetHash code 等于和实施 IEquatable&LT ;&GT; 顶点过,如:

... then override GetHashCode and Equals and implement IEquatable<> in Vertex too, e.g.

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

这篇关于C# - 定义自定义按键的HashSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆