It depends on your actual case, that is the information you need to retrieve from a collection.
In some cases, an object could have a limited knowledge of its environment within the collection. For instance, doubly-linked lists may work this way. A
Car will know both the previous and the next elements, and use this information to perform some action or manifest some behavior (for instance, a robot car
current might follow
current.Previous and send signals to
current.Next so the next one would follow the
current car. Or one may decide that the behavior of a doubly-linked list is the matter of the list itself (and the code processing the list), and it's not the
Car's business to know the previous or the next car. In this case, the list will use a generic wrapper, such as
DoublyLinkedListItem<T>, and it's this item which will contain both the
Car object and the references to the previous and next items.
In other cases, you would rather put the logic outside the
Car class, either in the collection itself (such as a
Train is a collection of
RailwayCars with its proper logic which has nothing to do within
RailwayCar), or in a very different class.
Finally, there are cases where the logic belongs to the
Car itself and depends on the collection, but the knowledge of the
Car of its surroundings doesn't need to be extensive. Let's take an example where a car needs to know the total horsepower of the cars in the collection when starting the engine. In this case, instead of giving to the car the reference to the entire collection (and let every car loop through the whole collection and do the math, individually), you may simply compute the sum and give it to the car:
horsepower = cars.sum(c => c.horsepower);