gh0stc0de
gh0stc0de

Reputation: 113

Generic list of generics with same base class

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?

Upvotes: 2

Views: 194

Answers (1)

Ashkan Mobayen Khiabani
Ashkan Mobayen Khiabani

Reputation: 34180

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>))
{

}

Upvotes: 2

Related Questions