Click here to Skip to main content
15,942,401 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi guys!

How are you?
We are from Argentina
Sorry but my english isn't very good.

I have got an exercise to resolve with OOP and we are looking for the best way to solve it

The problem to solve is count the number of instances of any subtype (Car, Truck) in a supertype collection (Vehicle)

http://img808.imageshack.us/img808/9120/problemni.png[^]

IList<Vehicle> vehicles = new List<Vehicle>();

Car aCar = null;
Truck aTruck = null;

aCar = new Car();
vehicles.Add(aCar);

aCar = new Car();
vehicles.Add(aCar);

aCar = new Car();
vehicles.Add(aCar);

aTruck = new Truck();
vehicles.Add(aTruck);

aTruck = new Truck();
vehicles.Add(aTruck);

// 3 cars
// 2 trucks

int cars = 0;
int trucks = 0;

foreach(Vehicle v in vehicles) {
    if(v is Car){
        cars++;
    } else if(v is Truck){
        trucks++;
    }
}


is there a better way to solve this problem, without using clause "is Type"?
Cheers!
Fernando Lopez Guevara
Posted
Comments
Dalek Dave 10-Sep-10 3:26am    
Your English is perfectly understandable my friend.

I think in order to have counters you need to get type of each of them atleat once. Thus your code:
C#
foreach(Vehicle v in vehicles) 
{    
  if(v is Car)
  {        
    cars++;    
  } 
  else if(v is Truck)
       {        
          trucks++;    
       }
}

Looks fine. :thumbsup:
 
Share this answer
 
May be this alternate helps you

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{

    class Vehicle
    {
        public static int Count = 0;
        public Vehicle()
        {
            Count++;
        }
    }

    class Car :Vehicle
    {
        public static int Count = 0;
        public Car()
        {
            Count++;
        }
    }

    class Truck : Vehicle
    {
        public static int Count = 0;
         public Truck()
        {
            Count++;
        }
    }

    class Class3
    {
        public static void Main()
        {
            Vehicle V1 = new Car();
            Vehicle V2 = new Car();

            Vehicle V3 = new Truck();

            Console.WriteLine("No of Cars =" + Car.Count);
            Console.WriteLine("No of Truck =" + Truck.Count);
            Console.WriteLine("No of Vehicle=" + Vehicle.Count);

        }
    }
}
 
Share this answer
 
i could it! and i want to share the code with you =)

using System.Collections.Generic;
using System;
namespace Visitor {
    public interface IVisitor {
        void Visit(Car c);
        void Visit(Truck t);
    }
    public class PaintVisitor : IVisitor {
        public void Visit(Car car) {
            car.Paint("red");
        }
        public void Visit(Truck truck) {
            truck.Paint("blue");
        }
    }
    public abstract class Vehicle {
        private string _color = "Black";
        public void Paint(string color) {
            this._color = color;
        }
        public abstract void Accept(IVisitor v);
        public override string ToString() {
            return string.Format("{0} - {1}", this.GetType(), this._color);
        }
    }
    public class Car : Vehicle {
        public override void Accept(IVisitor v) {
            v.Visit(this);
        }
    }
    public class Truck : Vehicle {
        public override void Accept(IVisitor v) {
            v.Visit(this);
        }
    }
    public class Program {
        public static void Main(string[] args) {
            List<Vehicle> vehicles = new List<Vehicle>();
            vehicles.Add(new Car());
            vehicles.Add(new Truck());
            vehicles.Add(new Car());
            vehicles.ForEach(x => Console.WriteLine(x));
            PaintVisitor pVisitor = new PaintVisitor();
            vehicles.ForEach(x => x.Accept(pVisitor));
            vehicles.ForEach(x => Console.WriteLine(x));
            Console.Read();
        }
    }
}


thanks everyone
 
Share this answer
 
Khaniya thanks!

Now if i wanna paint all cars but no the trucks?

IList<Vehicles> vehicles = ......

foreach(Vehicle v in vehicles) {
    if(v is Car){
        v.Paint("Red");
    }
}


the point isn't ask for the type of instance, i can't solve it!!

my teacher told me, that the solution for this problem is "Double Dispatching" (Visitor) but i don't know how implement this pattern, any idea?
 
Share this answer
 
Comments
Chris Trelawny-Ross 10-Sep-10 18:00pm    
Sound like you're asking us to solve a problem your teacher has set you. Perhaps asking one of your fellow students what the teacher said in class about Double Dispatch would be the way to go?
Chris Trelawny-Ross 10-Sep-10 18:05pm    
I also recommend Googling Double Dispatch and Visitor Pattern. If you really want to learn OO programming, reading the Wikipedia articles, and figuring out what they mean, will serve you far better in the long run than having one of us provide the answer to a test your teacher has set.
Khaniya 11-Sep-10 6:12am    
Hi Fernando Lopez
Your question is very interesting
thought I do not have more experience with Designing
but I think you are miss guided.
It is not Possible by Visitor design that only Car object is painted
anyway if you get solution put it here

Thanks
When you are counting Car or Truck, it is fine with your solution. "is" operator is quite capable of determining the type of an object.

For more simplistic an On demand logic, you can also use LINQ to filter out the element from the list.

int cars = vehicle.Where(item => item is Car).Count;


Here Where allow you to filter elements based on its type as well.

Another implementation could be use of ObservableCollection.

ObservableCollection notifies when a new object is added or removed. You can handle CollectionChanged event to get your counter updated when a new object is added.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900