List.contains не работает, как надеялись
-
23-10-2019 - |
Вопрос
Если у меня есть объект типа MyBull
и List<MyBull> orig
:
// Just an example
MyBull x = getMeTheObjectWithIdFromDB(9);
orig.add(x);
// Again same? data object
MyBull y = getMeTheObjectWithIdFromDB(9);
Почему это ложь тогда?
// This is false, even though all the properties
// of x and y are the same.
orig.Contains<MyBull>(y);
Решение
По умолчанию объекты будут выявлять справочное равенство. Если вам нужны пользовательские правила, такие как равенство на основе полей ID, вам необходимо переопределить Equals
а также GetHashCode
методы
Другие советы
Если вы можете использовать LINQ, то вы можете
class Vessel
{
public int id { get; set; }
public string name { get; set; }
}
...
var vessels = new List<Vessel>() { new Vessel() { id = 4711, name = "Millennium Falcon" } };
var ship = new Vessel { id = 4711, name = "Millencolin" };
if (vessels.Any(vessel => vessel.id == ship.id))
Console.Write("There can be only one!");
Это потому, что экземпляры Mybull сравниваются с помощью ссылки. С точки зрения с .net, x и y оба разные случаи и поэтому не равны.
Чтобы обойти это, вам придется переопределить методы равных и геташкодов (Что означает, что вы, вероятно, должны реализовать IEquatable<MyBull>
и переопределите == и! = Операторы тоже).
Реализует ли ваш объект MyBull IEquatable<T>.Equals
? Этот метод будет определять равенство двух объектов
Запрашивается OP
Ваш класс MyBull будет реализовать i -equatable
public class MyBull : IEquatable<MyBull>
И тогда вам нужно будет переопределить Equals
метод
public bool Equals(MyBull theOtherMyBull)
Как упоминает Дэвид Нил ниже, это лучше всего используется, когда вы сравниваете объекты того же типа-что вы. Переопределение Object.Equals и Object.gethashCode тоже будет работать.