Reputation: 41
I'm still getting my feet wet with OO and C#. I'm sure this is a simple question and I think I know the answer, but I want to be sure.
If I have a class called Car
and another class called Ford
which inherits from Car
, and yet another class called Mustang
which inherits from the Ford
class.
Is it acceptable/possible to create a method that accepts a collection of Car
objects and then when I call that method actually pass to that method a collection of Mustang
(or Ford
) objects since they are in fact Car
objects?
My thought is that this should be possible, with the understanding that I would only be able to access Properties\Methods of the Car
class. Am I way off base on this?
Also, if I am right, that you can do this: do you need to cast the Mustang
collection to a Car
collection in the call to the method?
Upvotes: 4
Views: 3079
Reputation: 4369
You can do this, passing a List<Car>
containing a Ford
:s for example:
public void Test()
{
// This works:
var fords = new List<Car> {new Ford()};
FixCars(fords);
// This does not work (since you cannot pass non car-typed list):
// var mustangs = new List<Ford> {new Ford()};
// FixCars(fords);
}
public void FixCars(List<Car> cars)
{
// Do stuff, for example check actual type and do specialized things:
foreach (var car in cars)
{
var ford = car as Ford;
if (ford != null)
ford.Honk();
}
}
public class Car
{
}
public class Ford : Car
{
public void Honk() {}
}
Upvotes: 0
Reputation: 14522
Others have already explained various aspects of sending a collection of Mustangs as a parameter to a different method, then I'll just add in a little info which you might find useful as well.
If you have a collection of Cars List<Car>
you can get only the Mustangs out of it by:
IEnumerable<Mustang> mstngs = cars.OfType<Mustang>();
List<Mustang> mstngsLst = mstngs.ToList();
And if you have a collection of Mustangs List<Mustang>
you can cast them all into cars with:
IEnumerable<Car> cars = mstngs.Cast<Car>();
List<Car> carsLst = cars.ToList();
Converting back into a list is not a must, by the way. It depends on what you need to do with the collection.
Upvotes: 1
Reputation: 48114
If you're only going to access methods and properties in the Car
class there is no reason to pass a list of Mustangs
. Instead you should just deal with your Mustangs
as if they were Cars
. That's one of the main points of inheritance. You can simply create a list of type car List<Car>
then add your Mustangs
to it. Then pass the list of type Car
. This is more extensible because it can accept any object which inherits from Car
and since you're only using properties/methods from Car
it's as strict of a definition as you need.
If you want specific behavior in the Mustang
class but a common interface for invoking that behavior define the method in Car
then override it in Mustang
. Again, this is more extensible because when you create a NineEleven
class you can also override this method thus giving you different behavior in the child classes without actually exposing their type.
Upvotes: 0
Reputation: 203827
No, that's not possible.
So if we have a function that accepts a List<Car>
types. Clearly that function ought to be able to add a Prius
to that list, no? Well, if you were allowed to pass a List<Mustang>
to this method you'd have just added a Prius
to a List<Mustang>
, clearly that would be bad.
Now if, rather than passing a List
, the method had a parameter of IEnumerable
or one of certain other read only collection types then it's possible it's "covariant". In that case, you could accept, as an example, an IEnumerable<Car>
and pass it a List<Mustang>
because you're never adding to the list, you're only accessing various elements, and as long as all of the Mustang
objects are Car
objects that's not a problem.
The design also seems a bit...off. I wouldn't think that Ford
should inherit from Car
. Ford
isn't a car, it's a brand, a company, a type of car. Mustang
is a car, so it makes sense for it to inherit from one. I would create a new type, say Manufacturer
of which you could create Ford
, Toyota
, etc. and make that a (read only) property of Car
.
Upvotes: 5