C # - Список<T>.Remove() всегда удаляет первый объект в списке

StackOverflow https://stackoverflow.com/questions/1434580

Вопрос

Работаю в Visual Studio 2008 (C #)...Я использую коллекцию списков для хранения экземпляров моего пользовательского класса (Shift).

Я хочу удалить определенный сдвиг из списка, используя метод Remove.

Но List.Remove() всегда удаляет первый найденный элемент.

Я внедрил интерфейс IComparable для своей смены, я подумал, что этого будет достаточно, затем я добавил реализацию IEqualityComparer, и это по-прежнему не имеет никакого эффекта.

Вот выдержка с моей реализацией:

сопоставимые участники по региону

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

конечный регион

участники region i EqualityComparer

    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", вызов "Удалить" ("12:00-16:00") приводит к удалению "8:00 - 15:00", а последний остается в коллекции!

Что здесь не так?Спасибо

Это было полезно?

Решение

Вы можете переопределить 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).

Другие советы

IComparable обычно не используется для сравнения на равенство (он используется для упорядочивания), поэтому List<T>.Remove() игнорирует это.

IEqualityComparer не является эквивалентом IComparable в целях равенства.Предполагается, что это будет реализовано с помощью объект сравнения - то есть объект, который сравнивает другие объекты за равенство.Если вы хотите, чтобы сравнения на равенство были присущи вашему классу, то вам скорее нужно реализовать IEquatable<T>.Или просто переопределить Object.Equals() и Object.GetHashCode() в вашем классе, без реализации каких-либо интерфейсов.

Удалить виды использования EqualityComparer<T>.Default чтобы определить равенство и выбрать, какой объект удалить, который будет использовать IEquatable<T> если это реализовано на вашем объекте, в противном случае он будет использовать равенство ссылок.

У вас есть два варианта получить желаемое поведение:

1) Осуществить сдвиг IEquatable<T> (не просто переопределить Object.Equals или создать метод, но сделать Shift - Shift : IEquatable<Shift>)

2) Использовать List<T>.RemoveAt

В приведенном вами примере вы вызываете:

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

"12:00 - 16:00" в данном случае это String значение, а не фактическое Shift объект.Убедитесь, что в вашем CompareTo метод, который вы кодируете, - это правильное приведение String ценность для Shift объект.В противном случае, когда он сравнивает время запуска...все может пойти наперекосяк.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top