我期望使用指定的EqualityComparer创建的HashSet在Remove操作上使用该comparer。特别是因为Contains操作返回true!
以下是我正在使用的代码:
public virtual IEnumerable<Allocation> Allocations { get { return _allocations; } }
private ICollection<Allocation> _allocations;
public Activity(IActivitySubject subject) { // constructor
....
_allocations = new HashSet<Allocation>(new DurationExcludedEqualityComparer());
}
public virtual void ClockIn(Allocation a)
{
...
if (_allocations.Contains(a))
_allocations.Remove(a);
_allocations.Add(a);
}
下面是一些快速而又脏的LINQ,它让我获得了我想要的逻辑,但我猜测基于EqualityComparer的HashSet删除会明显加快。
public virtual void ClockIn(Allocation a)
{
...
var found = _allocations.Where(x => x.StartTime.Equals(a.StartTime) && x.Resource.Equals(a.Resource)).FirstOrDefault();
if (found != null)
{
if (!Equals(found.Duration, a.Duration))
{
found.UpdateDurationTo(a.Duration);
}
}
else
{
_allocations.Add(a);
}
任何人都可以建议为什么在包含成功时删除会失败?
干杯,
Berryl
===编辑===比较器
public class DurationExcludedEqualityComparer : EqualityComparer<Allocation>
{
public override bool Equals(Allocation lhs, Allocation rhs)
{
if (ReferenceEquals(null, rhs)) return false;
if (ReferenceEquals(lhs, null)) return false;
if (ReferenceEquals(lhs, rhs)) return true;
return
lhs.StartTime.Equals(rhs.StartTime) &&
lhs.Resource.Equals(rhs.Resource) &&
lhs.Activity.Equals(rhs.Activity);
}
public override int GetHashCode(Allocation obj) {
if (ReferenceEquals(obj, null)) return 0;
unchecked
{
var result = 17;
result = (result * 397) ^ obj.StartTime.GetHashCode();
result = (result * 397) ^ (obj.Resource != null ? obj.Resource.GetHashCode() : 0);
result = (result * 397) ^ (obj.Activity != null ? obj.Activity.GetHashCode() : 0);
return result;
}
}
}
===更新 - 固定===
好吧,好消息是HashSet没有被破坏并且完全正常工作。对我来说,坏消息是当我在检查树上的树叶时看不到森林时,我是多么令人难以置信的愚蠢!答案实际上是在上面发布的代码中,如果你看一下创建的类和&amp;拥有HashSet,然后再看看Comparer,找出它有什么问题。第一个发现它的简单点。
感谢所有看过代码的人!
答案 0 :(得分:1)
嗯,“有效”的代码似乎在忽略StartTime
时会查看Resource
和Activity
,而您的IEqualityComparer<Allocation>
实现会查看这三个代码。你的问题可能与此有关吗?
另外:您的StartTime
,Resource
和Activity
属性是否不变?否则,由于它们会影响您的GetHashCode
结果,我认为您可能会违反HashSet<Allocation>
。