Delegates are very useful to act as object factories. In the example below, it is used to allow the function to build another object based on it, while keeping the function unaware about types.
namespace Microsoft.MSDN.Wiki.Samples
{
class Vehicle
{
int Price;
}
class Car : Vehicle
{
protected Car(string model, int passengers)
{
}
public static Car Create(string model, int passengers)
{
// Perform some check and create a new instance
return new Car(model, passengers);
}
public Vehicle FakeClone(Vehicle src)
{
// Cars are special in our example, and will not be cloned
// return the original object instead
return src;
}
}
class Bus : Vehicle
{
private string model;
private int passengers;
private int cargo;
protected Bus(string model, int passengers, int cargo)
{
// Assign variables
this.model = model;
this.passengers = passengers;
this.cargo = cargo;
}
public static Bus Create(string model, int passengers, int cargo)
{
// TODO: Perform some check and create a new instance
return new Bus(model, passengers, cargo);
}
public Vehicle CloneSpecial(Vehicle src)
{
// TODO: Perform some check and clone the instance
Bus bus = (Bus)src;
return new Bus(bus.model, bus.passengers, bus.cargo);
}
}
class Program
{
public delegate Vehicle CreateNewVehicle(Vehicle src);
public void ProcessBus(Bus bus)
{
ProcessVehicle(bus, bus.CloneSpecial);
}
public void ProcessCar(Car car)
{
ProcessVehicle(car, car.FakeClone);
}
public void ProcessVehicle(Vehicle source, CreateNewVehicle factory)
{
// This function might need to clone the vehicle. Use the delegate
// so the caller can control the creation
bool needToCloneObject = true;
if (needToCloneObject)
{
Vehicle newObj = factory(source);
if (newObj != null)
{
// Now we have a new object to work with
}
}
}
[STAThread]
public static void Main(string[] args)
{
}
}
}
As you can see we can take the knowledge about the creation logic outside the function when pure inheritance does not work (e.g. having a generic Clone() function in Vehicle) or when the logic changing depending on the context. For example, you might need to clone in a specific way on one condition and clone it differently on another condition.