C # - Список<T>.Remove() всегда удаляет первый объект в списке
-
07-07-2019 - |
Вопрос
Работаю в 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
объект.В противном случае, когда он сравнивает время запуска...все может пойти наперекосяк.