2

I'm trying to implement a generic list of generic objects where the types of the generics objects in the List have the same base class.

A simplified scenario would be: I want to have a garage with areas of vehicles. On area would have cars and the other would have bikes.

Here's a small example:

    public class MyGarage
    {
        public List<Area<Vehicle>> Create()
        {
            var vehicles = new List<Vehicle> { new Car(), new Bike() };
            var carArea = new Area<Car> { Vehicles = new List<Car>() };
            var bikeArea = new Area<Bike> { Vehicles = new List<Bike>() };
            var garage = new List<Area<Vehicle>>();

            // Not working - can't convert from Area<Car> to Area<Vehicle>
            garage.Add(carArea);
            garage.Add(bikeArea);
            
            return garage;
        }

        public void DoSomething()
        {
            var garage = Create();

            var area = garage.FirstOrDefault();
            if (area is Area<Car>)
            {
                // do something car related
            }
            else if (area is Area<Bike>)
            {
                // do something bike related
            }
        }
    }

    public abstract class Vehicle { }
    public class Car : Vehicle { }
    public class Bike : Vehicle { }

    public class Area<T> where T : Vehicle
    {
        public IEnumerable<T> Vehicles { get; set; }
    }

Any idea why this is not possible or what am I missing?

4
  • what is exactly that you are not able to do? Commented Apr 9, 2021 at 15:54
  • The lines with: garage.Add(carArea); and garage.Add(bikeArea); Commented Apr 9, 2021 at 15:55
  • you mean these: public class Car : Vehicle { } and public class Bike : Vehicle { }? Commented Apr 9, 2021 at 15:56
  • I mean the lines where I'm trying to add an Area of Car to a List of Area of Vehicle (I added a comment in the code): // Not working - can't convert from Area<Car> to Area<Vehicle> garage.Add(carArea); garage.Add(bikeArea); Commented Apr 9, 2021 at 16:02

1 Answer 1

2

Change

var carArea = new Area<Car> { Vehicles = new List<Car>() };
var bikeArea = new Area<Bike> { Vehicles = new List<Bike>() };

To

var carArea = new Area<Vehicle> { Vehicles = new List<Car>() };
var bikeArea = new Area<Vehicle> { Vehicles = new List<Bike>() };

Now your carArea and bikeArea is a Area<Vehicle> (which your garage expects) and each have its own related vehicles, which will work in your methods.

and to get the type of vehicle in the list:

if(area.GetType() == typeof(List<Car>))
{

}
Sign up to request clarification or add additional context in comments.

6 Comments

This compiles, but I lose the information of the area type. I can't distinguish between Area<Car> and Area<Bike>. I later want to check if a specific area in the garage is a bike or car area.
@gh0stc0de please check my updated answer.
please check again
@gh0stc0de Why are you trying to organize them in the same list if you want to distinguish them from one another? Why not have separate Area<T> properties per vehicle instead then?
@AshkanMobayenKhiabani This works. (I assume you meant if(area.Vehicles.GetType() == typeof(List<Car>)))
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.