在这种情况下,当一个成员被编辑成与另一个成员相等时,强制HashSet重新计算哈希值并清除重复项的正确方法是什么?
我知道不应该期望这种情况会自动发生,因此我尝试了一些方法,比如将HashSet与自身进行交集操作,然后将其重新分配给一个构造函数调用,该构造函数引用自身和相同的EqualityComparer。我本以为后者肯定会起作用,但实际上并没有。
唯一成功的方法之一是从其转换为其他容器类型(例如List)重建HashSet,而不是直接从它本身重建。
类定义:
我知道不应该期望这种情况会自动发生,因此我尝试了一些方法,比如将HashSet与自身进行交集操作,然后将其重新分配给一个构造函数调用,该构造函数引用自身和相同的EqualityComparer。我本以为后者肯定会起作用,但实际上并没有。
唯一成功的方法之一是从其转换为其他容器类型(例如List)重建HashSet,而不是直接从它本身重建。
类定义:
public class Test {
public int N;
public override string ToString() { return this.N.ToString(); }
}
public class TestClassEquality: IEqualityComparer<Test> {
public bool Equals(Test x, Test y) { return x.N == y.N; }
public int GetHashCode(Test obj) { return obj.N.GetHashCode(); }
}
测试代码:
TestClassEquality eq = new TestClassEquality();
HashSet<Test> hs = new HashSet<Test>(eq);
Test a = new Test { N = 1 }, b = new Test { N = 2 };
hs.Add(a);
hs.Add(b);
b.N = 1;
string fmt = "Count = {0}; Values = {1}";
Console.WriteLine(fmt, hs.Count, string.Join(",", hs));
hs.IntersectWith(hs);
Console.WriteLine(fmt, hs.Count, string.Join(",", hs));
hs = new HashSet<Test>(hs, eq);
Console.WriteLine(fmt, hs.Count, string.Join(",", hs));
hs = new HashSet<Test>(new List<Test>(hs), eq);
Console.WriteLine(fmt, hs.Count, string.Join(",", hs));
输出:
"Count: 2; Values: 1,1"
"Count: 2; Values: 1,1"
"Count: 2; Values: 1,1"
"Count: 1; Values: 1"
根据最终成功的方法,我可能可以创建一个扩展方法,使 HashSet 自己转储到本地列表中,清除自身,然后从该列表重新填充。
这真的有必要吗?还是有更简单的方法吗?