gwizardry
gwizardry

Reputation: 511

Not getting the type safety of generics and when to use generics

I'm unclear on the differences between

public class MyVehicleCollection<T> where T : Vehicle
{
     private List<T> listofVehicles = new List<T>();

     public void AddVehicle(T v) { listofVehicles.Add(v); }
}

and

public class MyVehicleCollection<Vehicle>
{
     private List<Vehicle> listofVehicles = new List<Vehicle>();

     public void AddVehicle(Vehicle v) { listofVehicles.Add(v); }
}

I don't see why in both cases its only possible to add types derived from Vehicle to the collection. I also don't see why i'd need to create additional collection classes for containing Motobike : Vehicle in the non-generic case.

Many thanks in advance.

Upvotes: 1

Views: 100

Answers (5)

Paddy
Paddy

Reputation: 33857

You example doesn't show the benefit necessarily. Say, for example, you created a super new type of data structure that contains child lists:

public SuperFastForwardOnlyList<T> : where T : IEnumerable
{
    public void AddList(T childList);

    //Crazy new algorithm here that is going to earn you a fortune, but must use collections     
    //of the same type.
}

You can then use this with any type of enumerable, ensuring that it meets the constraints for your algorithm:

SuperFastOnlyList<IList> listOfLists = new SuperFastOnlyList<IList>();

listOfLists.Add(new List());  //Fine
listOfLists.Add(new object()); //Whoops - compile time error.

This example is also a little contrived, but might be more illuminating?

Upvotes: 0

Tigran
Tigran

Reputation: 62246

I think you should consider not only class declaration, but also method (may be in this way it will be clearer)

//somewhere in the code have a method
public static string GetVehicleName<T>(T vehicle)  where T : Vehicle, new()
{
    return vehicle.GetVehicleName();
}

//abstract class Vehicle
public abstract class Vehicle
{
    public abstract string GetVehicleName ();
}

//Child class 
public class Car : Vehicle
{  
   public override string GetVehicleName()
   {
     return "Car";
   }
}

and after use it, like

GetVehicleName(new Car()); //will return "Car"

This is not production ready code, just an example to give you, hope, an idea.

It bascially creates and abstraction layer for a function that can host any type of Vehicles

Hope this helps.

Upvotes: 0

Mongus Pong
Mongus Pong

Reputation: 11477

You would generally use it to enforce the types accepted by your class - as long as they derive from Vehicle.

If you have

class Truck : Vehicle {}

and

class Van : Vehicle {}

You can declare

var x = new MyVehicleCollection<Truck> ();

Then the following would result in a compiler error :

x.AddVehicle ( new Van () );

Upvotes: 1

Henk Holterman
Henk Holterman

Reputation: 273219

Your second form is not bound to Vehicle at all:

public class MyVehicleCollection<Vehicle>
{
}

...

var coll = new MyVehicleCollection<string>();

From your description, you don't seem to need generics at all.

public class MyPlainVehicleCollection  //<Vehicle>  no Type Parameter
{
     private List<Vehicle> listofVehicles = 
             new List<Vehicle>();  // class Vehicle

     public void AddVehicle(Vehicle v) { listofVehicles.Add(v); }
}

also don't see why i'd need to create additional collection classes for containing Motobike : Vehicle

You don't :

var garage = new MyPlainVehicleCollection();
garage.Add(new Motobike ());

Upvotes: 1

The difference between the two is not at runtime but at compile time.

In the first case you can only declare MyVehicleCollection with types that are Vehicle or derived from Vehicle.

In the second case you can declare MyVehicleCollection with any type as @Henk Holterman already said.

Upvotes: 0

Related Questions