SJMan
SJMan

Reputation: 1607

Cloning Derived Types In a Single Method

I have a non Abstract Base class Vehicle which has three derived types.

I am looking at a service called VehicleBuilder Which would have a method CloneVehicle which takes a parameter of Vehicle type and returns a cloned object for all three derived types.

Here's my CloneVehicle

public Vehicle CloneVehicle (Vehicle v)
{
   var newVehicle = ClonebaseVehicle(v); // Clones all the types in the Base class
   if(Vehicle.Type == Vehicles.Tractor)
    {
        // Clone individual fields
        var tractor = new Tractor();
        tractor = newVehicle as Tractor;
        tractor.TractorCapacity  = 50 ; // tractor is coming null here
        return tractor; 
    }
}

I want to reuse ClonebaseVehicle and cannot create a constructor as the classes are coming from a diferrent DLL. Any other ways where I can clone the dervied objects using a base class reference ?

I cannot change the Vehicle class or any of its derived classes to create an abstract method in it

Upvotes: 3

Views: 50

Answers (1)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37113

Within your CloneBaseVehicle-method you should provide all members from your base-class. If there are many members you may also use reflection to do this:

Vehicle CloneBaseVehicle(Vehicle v)
{
    Tractor t;
    switch v.Type
    {
        case Vehicles.Tractor:
            t = new Tractor();
        case Vehicles.Car:
            t = new Car();
        case Vehicles.Motorcycle:
            t = new Motorcycle();
    }

    // now copy the common properties
    t.MyProperty = v.MyProperty;
    t.AnotherProperty = v.AnotherProperty;

    return t;
}

public Vehicle CloneVehicle (Vehicle v)
{
    var newVehicl = CloneBaseVehicle();

    switch(v.Type)
    {
        case(Vehicles.Tractor):
            var tractor = newVehicle as Tractor;
            tractor.TractorCapacity  = 50 ;
            break;
        case Car:
            ...
            break;
    }
    return newVehicle;
}

A reflection-based approach for CloneBaseVehiclecould look like this:

Vehicle CloneBaseVehicle(Vehicle v)
{
    Tractor t;
    switch v.Type
    {
        case Vehicles.Tractor:
            t = new Tractor();
        case Vehicles.Car:
            t = new Car();
        case Vehicles.Motorcycle:
            t = new Motorcycle();
    }

    var properties = typeof(Vehicle).GetProperties();
    foreach(var p in properties)
        p.SetValue(t, v.GetValue(p));

    return t;
}

No matter which of the two approaches you chose you should be aware that when creating a Tractor from an existing Car you´re of course loosing all the special information that existed only in Car.

Upvotes: 3

Related Questions