Sean
Sean

Reputation: 163

C# Using foreach to iterate through a list containing 2 different object classes

Here's my problem.

I've got 2 classes that both inherit from a common class. I.E a car class and a van class which both inherit from a vehicle class. I added them to a common list of type vehicle. The car class has a noofseats attribute and the van has a weight attribute. Is there a way to iterate through them using a foreach loop and output based on whether they are a car class or van class?

foreach (van v in vehiclelist)
{
  lsttest.Items.Add(v.weight;)
}

foreach (car c in vehiclelist)
{
  lsttest.Items.Add(c.nofoseats;)
}

I get an error of: 'Unable to cast object of type 'Test.Car' to type 'Test.Van'.'

Is there an easy way to fix this or is it just not possible? Thanks

Upvotes: 1

Views: 16095

Answers (5)

dferraro
dferraro

Reputation: 6427

For me, the whole point of Polymorphism is so that I don't care what underlying type my object really is. While you could check what type it is easily using different methods already mentioned here, My answer would be to not do this at all. Instead, you should abstract away the different behavior into a common function and instead call that method. Quick example:

   class Vehicle
    {
        abstract public int GetMeasurement();
    }

    class Car : Vehicle
    {
       //cars are measured in numberOfSeats
       override public int GetMeasurement()
       {
          return numberOfSeats;
       }

        private int numberOfSeats;
    }

   class Van: Vehicle
   {
       //vans are measured by weight
       override public int GetMeasurement()
       {
          return weight;
       }

      private int weight;
   }

  foreach (Vehicle v in vehiclelist)
  {
     //I don't need to do any type checking: 
     //polymorphism magically gets the right value for me
     lsttest.Items.Add(v.GetMeasurement());
  }

The advantage to this is now I can re-use the same methods all over the place without ever having to care what Type I really am. Now I can do all kinds of cool things (APIs, etc) with a Vehicle: and later, if I want to add different vehicle types, I don't have to change anything. I create a new vehicle type, implement the GetMeasurement() function, and it magically works. When you start getting 3,5,15 different vehicle types you can easily see the advantage here.

Upvotes: 2

Boodinski
Boodinski

Reputation: 76

    static void Main(string[] args)
    {
        var vehicles = new List<Vehicle>();
        vehicles.Add(new Car() { NoOfSeats = 2 });
        vehicles.Add(new Car() { NoOfSeats = 4 });
        vehicles.Add(new Van() { Weight = 2000 });
        vehicles.Add(new Van() { Weight = 3000 });


        foreach (var vehicle in vehicles)
        {
            if (vehicle is Car)
            {
                Console.WriteLine("I'm a car");
            }
            if (vehicle is Van)
            {
                Console.WriteLine("I'm a van");
            }
        }

        Console.ReadKey();

    }

    class Vehicle
    {

    }

    class Car : Vehicle
    {
        public int NoOfSeats { get; set; }
    }

    class Van : Vehicle
    {
        public int Weight { get; set; }

    }
}

Upvotes: 0

BRAHIM Kamel
BRAHIM Kamel

Reputation: 13765

just check with 'is' Checks if an object is compatible with a given type. check MSDN

 foreach (vehicle c in vehiclelist)     
 {
    if(c is car)
    {
        //do this
    }
    else 
    { 
        //else it should be a van              
    }
 }

Upvotes: 3

L.B
L.B

Reputation: 116108

foreach (van v in vehiclelist.OfType<Van>())
{
}

Upvotes: 10

System Down
System Down

Reputation: 6260

You need to filter it by type, which is easy thanks to Linq:

foreach (van v in vehiclelist.Where(x=>x is van))
{

}

Upvotes: 4

Related Questions