List.Contains возвращает значение false, даже если кажется, что оно должно возвращать значение true - PullRequest
3 голосов
/ 17 февраля 2010
Sub pageload() Handles Me.Load
    Dim bom As New List(Of Car)

    Dim car1 As New Car With {.Name = "Pea", .Year = 2}
    Dim car2 As New Car With {.Name = "Pea", .Year = 2}

    bom.Add(car1)

    MsgBox(bom.Contains(car2))
End Sub

ПОЧЕМУ ??? Я имею в виду, что объект имеет точно такие же данные, так почему он говорит, что он не содержится?

Ответы [ 3 ]

15 голосов
/ 17 февраля 2010

Метод Contains проверяет равенство, вызывая метод Equals для объектов. Если вы не переопределите метод Equals в классе Car и не реализуете свои собственные средства сравнения, экземпляры Car будут считаться равными с помощью ссылочной идентичности (являющейся точно таким же объектом) на основании их равного содержания.

Те объекты, которые вы создали, определенно не являются тем же объектом. Доказательство: изменение одного не изменит другого.

1 голос
/ 17 февраля 2010

Ключ в том, что car является ссылочным типом , а не типом значения. Два создаваемых вами автомобильных объекта - совершенно разные вещи. Каждый из них указывает на другое место в памяти, даже если они имеют одинаковые свойства. Думайте о них как об идентичных близнецах. Один садится в грузовик. Если вы спросите, есть ли в грузовике другой , ответ будет отрицательным, хотя в некотором смысле они точно такие же .

Если бы вы определили car2 и затем установили его равным car1 (Dim car2 As New Car = car1), то вам пришлось бы указывать на точно такое же место в памяти. Ваш результат был бы правдой. Обе переменные ссылались бы на один и тот же объект автомобиля.

Теперь, если бы это был тип значения , например, целое число или дата (или структура. И строка ведет себя так же.), То любые одинаковые значения будут считаться одинаковыми. Вы кладете 10 долларов в машину, и я спрашиваю, есть ли 10 долларов в машине. Ответ - да, и не важно, были ли это мои 10 долларов или ваши 10 долларов.

Ваш пример является отличным примером ключевой разницы в поведении ссылочных типов и типов значений.

Для ссылочных типов по умолчанию свойство Equals проверяет, являются ли два объекта ссылками на одно и то же место в памяти, а не одинаковыми ли все значения. ( Содержит использует свойство Равно .) Вы можете переопределить это поведение для определенных объектов, если хотите.

0 голосов
/ 17 февраля 2010

Ваши две машины полностью независимы друг от друга.

Contains проверяет, указывает ли какой-либо элемент списка на один и тот же объект , как и указанный вами параметр.И не то, являются ли эти два объекта логически равными.

Если вы хотите, чтобы это делалось, вы должны переопределить Equals -метод вашего Car

...