C# - List.Remove() 始终删除列表中的第一个对象

发布于 2024-08-05 03:18:52 字数 1264 浏览 6 评论 0原文

在 Visual Studio 2008 (C#) 中工作... 我使用 List 集合来存储自定义类 (Shift) 的实例。

我想使用“删除”方法从列表中删除某个班次。

但 List.Remove() 总是删除它找到的第一个项目。

我已经为我的 Shift 实现了 IComparable 接口,我认为这已经足够了,然后我添加了 IEqualityComparer 的实现,但它仍然没有效果。

这是我的实现的摘录:

地区I可比会员

 public int CompareTo(object obj)
    {
        移位 s1 = 这个;
        Shift s2 = (Shift)obj;
        if (s1.开始时间!= s2.开始时间)
            返回 s1.start.CompareTo(s2.start);
        别的
            返回 s1.end.CompareTo(s2.end);
    }

结束区域

地区 IEqualityComparer 成员

 public bool 等于(Shift x, Shift y)
    {
        
        if ((x.opening) != (y.opening)) 返回 false;
        if ((x.ending) != (y.ending)) 返回 false;
        if (!x.opening) if (x._start != y._start) return false;
        if (!x.close) if (x._end != y._end) return false;
        if (x.when != y.when) 返回 false;
        if (x.day!= y.day) 返回 false;
        if (x.EmployeeID != y.EmployeeID) 返回 false;
        返回真;
    }

    公共 int GetHashCode(Shift obj)
    {
        返回 obj.ToString().ToLower().GetHashCode();
    }

结束区域

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

这是怎么回事?谢谢

Working in Visual Studio 2008 (C#)...
I use a List collection to store instances of my custom class (Shift).

I want to delete a certain shift from the list by using the Remove method.

But List.Remove() always deletes the first item it finds.

I've implemented the IComparable interface for my Shift, I thought this would be enough, then I added an implementation of IEqualityComparer, and it still has no effect.

Here's the excerpt with my implementation:

region IComparable Members

    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

region IEqualityComparer Members

    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

And yet, still - when the List contains two shifts, say "8:00 - 15:00"; "12:00 - 16:00", calling Remove("12:00-16:00") results in "8:00 - 15:00" getting removed, and the latter one remains in the collection!

What's wrong here? Thx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

听,心雨的声音 2024-08-12 03:18:52

您可以覆盖 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) 中执行 null 检查。

You can override object.GetHashCode and 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);
}

You should also probably do a null check in Equals(x, y).

诗化ㄋ丶相逢 2024-08-12 03:18:52

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

出于平等目的,IEqualityComparer 并不等同于 IComparable。它应该由一个比较器对象实现 - 即比较其他对象是否相等的对象。如果您希望相等比较是您的类所固有的,那么您需要实现 IEquatable。或者只是在类上重写 Object.Equals()Object.GetHashCode(),而不实现任何接口。

IComparable is not normally used to compare for equality (it's used for ordering), so List<T>.Remove() ignores it.

IEqualityComparer is not an equivalent of IComparable for equality purposes. It is supposed to be implemented by a comparer object - that is, an object that compares other objects for equality. If you want equality comparisons to be inherent to your class, then you rather need to implement IEquatable<T>. Or just override Object.Equals() and Object.GetHashCode() on your class, without implementing any interfaces.

愿得七秒忆 2024-08-12 03:18:52

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

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

1) 让 Shift 实现 IEquatable(不仅仅是重写 Object.Equals 或创建方法,而是创建 Shift - Shift : IEquatable

2) 使用 List.RemoveAt

Remove uses EqualityComparer<T>.Default to determine equality and choose which object to remove, which will use IEquatable<T> if it's implemented on your object, otherwise, it will use reference equality.

You have two options to get the behavior you want:

1) Make Shift implement IEquatable<T> (not just override Object.Equals or make the method, but make Shift - Shift : IEquatable<Shift>)

2) Use List<T>.RemoveAt

迷迭香的记忆 2024-08-12 03:18:52

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

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

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

With the example you provided, you're calling:

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

"12:00 - 16:00" in this case, is a String value and not an actual Shift object. Make sure that in your CompareTo method that you're code is properly casting the String value to a Shift object. Otherwise, when it compares start times...things could go haywire.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文