开发者

Factory method for generic interface

I think this code is mortally wounded but would like some opinions before I take a new approach.

I am writing a factory method for the following interface.

public interface ITransformer<I, O>
{
   O Transform(I input);
}

Here is a possible implementation of the interface

public class CarToTruckTransformer : ITransformer<Car, Truck>
{
    public Truck Transform(Car input)
    {
        Truck output = new Truck();
        output.Seats = input.Seats - 2;
        output.BedSize = input.TrunkSize;
        output.Gunrack = true;
        return output;
    }
}

The first factory I did looks like this

static class Tr开发者_开发技巧ansformerFactory
{
    public static ITransformer<I, O> GetTransformer<I, O>()
    {
        if (typeof(I) == typeof(Car) && typeof(O) == typeof(Truck))
        {
            return (ITransformer<I, O>)new CarToTruckTransformer();
        }
        else
        {
            return null;
       }
    }
}

But I have to know the exact types when I call the factory method so it seems less than ideal.

ITransformer<Car, Truck> transf = TransformerFactory.GetTransformer<Car, Truck>();

I have also toyed with the following, but I'm afraid this may be a gross misuse of the dynamic keyword.

public class TransformerFactory2
{
    public static dynamic GetTransformer(VehicleBase input, VehicleBase output)
    {
        if (input.GetType() == typeof(Car) && output.GetType() == typeof(Truck))
        {
            return (ITransformer<Car, Truck>)new CarToTruckTransformer();
        }
        else
        {
            return null;
        }
    }
}

But it does allow me to get the factory syntax that I want.

dynamic transf = TransformerFactory2.GetTransformer(car, truck);

I've also considered the first option but calling the factory method with reflection so I could dynamically assign the type variables.

Ultimately, I would like the entire "transform" process to be contained in one reusable method and just implement new transformers when needed but I'm not there yet.

Is there a better or safer approach for this kind of situation?

Thanks for reading.


This is way off topic if you are interested in exploring OOP and Patterns but this specific example you are describing can be fairly neatly described using Func<I,O> delegates.

e.g.

var car = getSomeCar();
car.select(c => new Truck{
   :
   :
});

And you define select as a generic extension method on I

e.g.

public static O select<I,O>(this I input, Func<I,O> project)
{
   return project(input);
}

Just a thought.

Edit

Just tested this and it should work fine :) Renamed transform to select to highlight the similarity to the Linq operator.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜