5

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

端区

地区 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();
    }

端区

然而,仍然 - 当列表包含两个班次时,说“8:00 - 15:00”;"12:00 - 16:00",调用 Remove("12:00-16:00") 会导致 "8:00 - 15:00" 被删除,而后一个仍保留在集合中!

这里有什么问题?谢谢

4

4 回答 4

10

您可以覆盖object.GetHashCodeobject.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).

于 2009-09-16T18:07:23.907 回答
4

IComparable通常不用于比较相等性(它用于排序),因此List<T>.Remove()忽略它。

IEqualityComparer不是IComparable出于平等目的的等价物。它应该由一个比较器对象实现- 即一个比较其他对象是否相等的对象。如果您希望平等比较是您的类所固有的,那么您宁愿需要实现IEquatable<T>. 或者只是覆盖你Object.Equals()Object.GetHashCode()类,而不实现任何接口。

于 2009-09-16T18:14:10.633 回答
1

删除用于EqualityComparer<T>.Default确定相等性并选择要删除IEquatable<T>的对象,如果它在您的对象上实现,将使用哪个对象,否则,它将使用引用相等性。

您有两种选择来获得所需的行为:

1)使 Shift 实现IEquatable<T> (不仅仅是覆盖 Object.Equals 或制作方法,而是制作 Shift - Shift : IEquatable<Shift>

2) 使用List<T>.RemoveAt

于 2009-09-16T18:09:10.500 回答
0

使用您提供的示例,您正在调用:

List<Shift>.Remove("12:00 - 16:00");

"12:00 - 16:00"在这种情况下,是一个String值,而不是一个实际的Shift对象。确保在您CompareTo的代码方法中正确地将String值转换为Shift对象。否则,当它比较开始时间时......事情可能会变得混乱。

于 2009-09-16T18:13:57.840 回答