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



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

代码

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

最新更新