Ваш код имеет некоторые проблемы.Во-первых, вы повторно используете один и тот же объект для каждой из ваших итераций.
Рассмотрим
List<Foo> foos = new List<Foo>();
Foo foo = new Foo();
foo.Bar = "Alpha";
foos.Add(foo);
foo.Bar = "Beta";
foos.Add(foo);
Вы заметите, что в вашем списке будет 2 элемента, но они будут ссылаться на один и тот же объект.Если вы перебираете список и проверяете Bar
, каждый из них вернет "Beta"
.
Вы хотите создать новый Foo
для каждого элемента.
List<Foo> foos = new List<Foo>();
Foo foo = new Foo();
foo.Bar = "Alpha";
foos.Add(foo);
Foo anotherFoo = new Foo();
anotherFoo.Bar = "Beta";
foos.Add(anotherFoo);
В терминах цикла это в основном означает создание объекта внутри цикла, а не снаружи.
while (someCondition)
{
Foo foo = new Foo();
// do your work, populate the object, etc.
// then check contains
if (!myList.Contains(foo))
myList.Add(foo);
}
Что касается проверки того, содержит ли коллекция объект, правильно ли вы переопределили Equals
и GetHashCode
?При работе с классами поведение по умолчанию заключается в простой проверке, равны ли ссылки на объекты.Если вы беспокоитесь о значениях , которые инкапсулируют объекты, то вам нужно предоставить логику для этого самостоятельно.В вашем классе вам нужно переопределить методы Equals
и GetHashCode
, чтобы реализовать желаемый метод определения равенства.
class Foo
{
public string Bar { get; set; }
public override int GetHashCode()
{
return this.Bar.GetHashCode();
}
public override bool Equals(object other)
{
Foo otherFoo = other as Foo;
if (otherFoo == null)
return false;
else
return this.Bar == otherFoo.Bar;
}
}
Теперь, когда Contains
пытается определить, находится ли объект уже всписок, он будет делать это на основе значений, содержащихся в объекте, а не ссылки на память.