Pierre Nilsson
Pierre Nilsson

Reputation: 25

Factory for lists

My apologies if this looks very much like a similar question I asked a few weeks back; I am learning.

I have a function that should return a List of objects - somewhat like a Factory. In the example below I have two classes Truck and Car who both inherit from the superclass Vehicle. The function does not work, but it should show what I want to accomplish.

EDIT: Forgot to say HOW it did not work. Well, the function creates a List of, for example, Trucks, but cannot return it since the return value must be a List of Vehicle. I do not know how to convert the created list or even if it can be converted.

Obviously I am primarily asking for advice how to get the damned thing to work! But I would also appreciate any ideas on how to get it more scalable - to have a "case" statement for every possible Vehicle class does not make me happy.

The v.Populate function is just there to fill the object with data from the DataReader. Should not affect the problem at hand.

Calling the function, in this instance I want a List with Truck objects: return PopulateList("Truck", gc);

private List<Vehicle> PopulateList(String type, GenericConnection gc)
{
    Vehicle v;
    var ret = new List<Vehicle>();
    var r = gc.ExecuteReader();
    while (r.Read())
    {
        switch (type)
        {
            case "Truck":
                v = new Truck();
                break;
            case "Car":
                v = new Car();
                break;
            default:
                throw new ArgumentException("Unknown Vehicle: " + type, "type");
        }
        v.Populate(r);
        ret.Add(v);
    }
    r.Close();
    return ret;
}

For clarity, here is a copy of the same function but now all non-essential code (mostly concerning the DataReader) is stripped away. The return value should be a List with exactly one empty object in it.

private List<Vehicle> PopulateList(String type)
{
    Vehicle v;
    var ret = new List<Vehicle>();
    switch (type)
    {
        case "Truck":
            v = new Truck();
        case "Car":
            v = new Car();
        }
    }
    ret.Add(v);
    return ret;
}

Upvotes: 0

Views: 2538

Answers (3)

Wiktor Zychla
Wiktor Zychla

Reputation: 48279

Why don't you use generics:

public interface IPopulate {
   void Populate( DbDataReader dataReader );
}

....
private List<T> PopulateList<T>( GenericConnection gc )
    where T : IPopulate, new()
{
    T v;
    var ret = new List<T>();
    var r = gc.ExecuteReader();
    while (r.Read())
    {
        v = new T();
        v.Populate(r);
        ret.Add(v);
    }
    r.Close();
    return ret;
}

You'd call it like

PopulateList<Truck>( connection );
PopulateList<Car>( connection );

Upvotes: 2

Azhar Khorasany
Azhar Khorasany

Reputation: 2709

Create a generic method:

public T CreateInstance<T>() where T : Vehicle, new()
{
    var obj = new T();
    return obj;
}

Usage:

var truck = CreateInstance<Truck>();
var car = CreateInstance<Car>();

Upvotes: 0

Tomek
Tomek

Reputation: 3279

You can create generic method:

private List<Vehicle> PopulateList<T>() where T: Vehicle
    {
        Vehicle v = new T();
        var ret = new List<Vehicle>();
        // main logic
        ret.Add(v);
        return ret;
    }

Upvotes: 0

Related Questions