在Visual Studio 2008中工作(C#)... 我使用List集合来存储我的自定义类(Shift)的实例。
我想使用Remove方法从列表中删除某个班次。
但List.Remove()总是删除它找到的第一个项目。
我已经为我的Shift实现了IComparable接口,我认为这已经足够了,然后我添加了IEqualityComparer的实现,它仍然没有效果。
以下是我的实施摘录:
地区IComparable会员
public int CompareTo(object obj) { Shift s1 = this; Shift s2 = (Shift)obj; if (s1.start.time != s2.start.time) return s1.start.CompareTo(s2.start); else return s1.end.CompareTo(s2.end); }
endregion
区域IEqualityComparer成员
public bool Equals(Shift x, Shift y) { if ((x.opening) != (y.opening)) return false; if ((x.closing) != (y.closing)) return false; if (!x.opening) if (x._start != y._start) return false; if (!x.closing) if (x._end != y._end) return false; if (x.when != y.when) return false; if (x.day != y.day) return false; if (x.EmployeeID != y.EmployeeID) return false; return true; } public int GetHashCode(Shift obj) { return obj.ToString().ToLower().GetHashCode(); }
endregion
然而,仍然 - 当列表包含两个班次时,说“8:00 - 15:00”; “12:00 - 16:00”,调用删除(“12:00-16:00”)导致“8:00 - 15:00”被删除,后者仍留在集合中!
这里有什么问题? THX
答案 0 :(得分:10)
您可以覆盖object.GetHashCode
和object.Equals
:
public override bool Equals(object obj)
{
if(obj == null)
{
return false;
}
return Equals(this, obj as Shift);
}
public override int GetHashCode()
{
return this.GetHashCode(this);
}
你也应该在Equals(x, y)
中进行空检查。
答案 1 :(得分:3)
IComparable
通常不用于比较相等(它用于排序),因此List<T>.Remove()
会忽略它。
IEqualityComparer
不等同于IComparable
。它应该由 comparer对象实现 - 也就是说,将其他对象进行相等性的对象。如果您希望等级比较是您的类固有的,那么您需要实现IEquatable<T>
。或者只是覆盖类上的Object.Equals()
和Object.GetHashCode()
,而无需实现任何接口。
答案 2 :(得分:0)
删除使用EqualityComparer<T>.Default
来确定相等性并选择要删除的对象,如果它在对象上实现,将使用IEquatable<T>
,否则,它将使用引用相等。
您有两种方法可以获得所需的行为:
1)制作Shift工具IEquatable<T>
(不仅仅是覆盖Object.Equals或制作方法,而是制作Shift - Shift : IEquatable<Shift>
)
2)使用List<T>.RemoveAt
答案 3 :(得分:0)
根据您提供的示例,您正在呼叫:
List<Shift>.Remove("12:00 - 16:00");
在这种情况下, "12:00 - 16:00"
是String
值,而不是实际的Shift
对象。确保在您的CompareTo
方法中,您的代码正确地将String
值转换为Shift
对象。否则,当它比较开始时间时...事情可能会变得混乱。