The key is that car
is a reference type, not a value type. The two car objects you create are completely separate things. Each points to a different place in memory, even though they happen to have all the same properties. Think of them like identical twins. One gets into a truck. If you ask if the other one is in the truck, the answer is no, even though in a sense they are exactly the same.
If you had defined car2
and then set it equal to car1 (Dim car2 As New Car = car1
), then you would have to pointers to the exact same place in memory. Your result would have been true. Both variables would have referred to the same car object.
Now, if this was a value type, like an integer or date (or structure. And a string behaves this way also.), then any values that are the same would be considered the same. You put $10 in a car, and I ask if $10 is in the car. The answer is yes, and it doesn't matter if it was my $10 or your $10.
You example is a great example of a key difference in how reference types and value types behave.
For reference types by default, the Equals property check to see if two objects are references to the exact same place in memory, not whether all the values are the same. (Contains uses the Equals property.) You could override that behavior for particular objects if you wished.