Passing Collections of Derived Objects in C #

I still wet OO and C # feet. I am 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 that inherits from Car , and another class called Mustang that inherits from Ford .

Is it possible / possible to create a method that accepts a collection of Car objects, and then when I call this method, they actually pass a collection of Mustang (or Ford ) objects to this method, since they are in fact Car objects?

My thought is that this should be possible, on the understanding that I can only access the properties \ Methods of the Car class. Am I really on this basis?

Also, if I'm right, you can do this: do you need to pass the Mustang collection to the Car collection when calling the method?

+4
source share
4 answers

No, It is Immpossible.

So, if we have a function that accepts List<Car> types. Clearly, this feature should be able to add the Prius to this list, no? Well, if you were allowed to pass a List<Mustang> this method, you would just add a Prius to the List<Mustang> , which would be bad.

Now, if instead of passing a List , the method had an IEnumerable parameter or one of some other read-only collection types, then it could be "covariant." In this case, you can take IEnumerable<Car> as an example and pass it List<Mustang> , because you never add to the list, you only get access to various elements and as long as all Mustang objects are Car objects, which not a problem.

The design also seems a bit ... off. I don't think Ford should inherit from Car . Ford is not a car, it is a brand, a company, a type of car. Mustang is a car , so it makes sense to inherit it. I would create a new type, say Manufacturer , from which you could create Ford , Toyota , etc. And make this property (read-only) Car .

+3
source

If you intend to access the methods and properties of the Car class, there is no reason to pass a list of Mustangs . Instead, you should simply deal with your Mustangs , as if they were Cars . This is one of the main points of inheritance. You can simply create a list of List<Car> car types and then add your Mustangs to it. Then pass the list of Car types. This is more extensible because it can accept any object that inherits from Car , and since you only use properties / methods from Car as the strict definition you need.

If you need specific behavior in the Mustang class, but the general interface for calling this behavior defines the method in Car , then redefine it in Mustang . Again, this is more extensible because when you create a NineEleven class, you can also override this method, thereby giving you different behaviors in child classes without actually exposing their type.

+1
source

Others have already explained various aspects of sending the Mustang collection as a parameter to another method, after which I will just add some little information that you may also find useful.

If you have a Cars List<Car> collection, you can only get Mustangs from it:

 IEnumerable<Mustang> mstngs = cars.OfType<Mustang>(); List<Mustang> mstngsLst = mstngs.ToList(); 

And if you have a Mustangs List<Mustang> collection, you can drop them on cars with:

 IEnumerable<Car> cars = mstngs.Cast<Car>(); List<Car> carsLst = cars.ToList(); 

Converting back to a list is optional, by the way. It depends on what you need to do with the collection.

+1
source

You can do this by passing a List<Car> containing 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() {} } 
0
source

All Articles