每次将重复对象添加到 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);
}
我正在使用 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);
}