每次将重复对象添加到 HashSet 时调用方法

Call Method Every time Duplicate Object Added to HashSet

我正在使用 HashSet 创建一个点列表,因为我不想在我的列表中出现重复的点。点具有三个属性 X 坐标(双)、Y 坐标(双)和标签(HashSet)。现在我想要的是每当我将重复点添加到 HashSet 时,它也会将重复点的标签添加到匹配点。

代码

using System;
using System.Collections.Generic;

namespace ConsoleAppTest
{
    internal static class Program
    {
        private static void Main()
        {
            try
            {
                var points = new Point2DHashSet()
                 {
                new Point2D(0,0,"Start"),
                new Point2D(10,0,"Int1"),
                new Point2D(10,10,"Int2"),
                new Point2D(0,10,"Int3"),
                new Point2D(0,0,"End")
                };

                Console.WriteLine(points.ToString());
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }

    public class Point2DHashSet : HashSet<Point2D>
    {
        public override string ToString()
        {
            var sb = new System.Text.StringBuilder();
            foreach (var pt in this)
            {
                sb.AppendLine(pt.ToString());
            }
            return sb.ToString();
        }
    }

    public class Point2D : IEquatable<Point2D>
    {
        public double X { get; set; }
        public double Y { get; set; }
        public HashSet<string> Tags { get; set; }

        public Point2D()
        {
            Tags = new HashSet<string>();
        }

        public Point2D(double x, double y, string tag) : this()
        {
            X = x;
            Y = y;
            Tags.Add(tag);
        }

        public override string ToString()
        {
            return $"{X:0.####},{Y:0.####},{string.Join(",", Tags)}";
        }

        public bool Equals(Point2D point)
        {
            return this.X == point.X && this.Y == point.Y;
        }

        public override bool Equals(object obj)
        {
            if (obj is null) return false;
            return obj is Point2D point3D && Equals(point3D);
        }

        public override int GetHashCode()
        {
            return X.GetHashCode() + Y.GetHashCode();
        }
    }
}

当前输出

0,0,Start
10,0,Int1
10,10,Int2
0,10,Int3

我想要的输出

0,0,Start,End
10,0,Int1
10,10,Int2
0,10,Int3

您的 Point2DHashSet 需要一个 Add 来执行此自定义逻辑“如果对象已经存在,则将传入点的标签添加到现有的点标签哈希集中。您不能替换派生集中的基础 Add,因为基础不是虚拟的,但你可以隐藏它:

public new bool Add(Point2D incoming){

  if(base.TryGetValue(incoming, out var existing))
    existing.Tags.UnionWith(incoming.Tags);
  else
    base.Add(incoming);
}

我想这就是你需要的..

请注意,您不会收到重复的标签,而且标签的显示顺序不一定与添加时的顺序相同。您的输出很容易是 0,0,End,Start

当前解决方案

        public new bool Add(Point2D point)
        {
            var sucess = base.Add(point);
            if (!sucess)
            {
                UpdateTags(point);
            }
            return sucess;
        }

        private void UpdateTags(Point2D point)
        {
            TryGetValue(point, out Point2D pt);
            pt.Tags.UnionWith(point.Tags);
        }