If you don't need public access to the generic type
In particular if SimpleCollagePatterns
is used exclusivly by the class that implements that particular interface (In this case ShapeBuilder
), then you don't need covariance.
There is a simple design pattern that relies on inheritance alone.
For example:
public interface IBuilder {
void Build();
}
public interface IBuilder<T> : IBuilder {
T BuildParameter {get;}
}
Note: The BuildParameter
corresponds to your BuildCollagePattern
Then you can implement the interface as such:
public class SpecificBuilder : IBuilder<Int32> {
// The specific constructor
public SpecificBuilder(int param) { BuildParameter = param; }
// Implement from IBuilder
public void Build() {
System.Console.WriteLine("Building with Int32: " + BuildParameter);
}
// Implement from IBuilder<T>
public Int32 BuildParameter {get; private set;}
}
Then you can pass around any IBuilder<T>
as an IBuilder
public class Program {
public static void Main() {
SpecificBuilder builder = new SpecificBuilder(42);
// SpecificBuilder implements IBuilder<Int32>
// Build accepts any IBuilder
// So this is legal:
Build(builder);
}
//
// Note this method accepts anything that inherits from IBuilder
//
public static void Build(IBuilder builder) {
builder.Build();
// If you'd need access to the BuildParameter of IBuilder<T>
// then this pattern fails you here.
// Unless of course you want to check for types and cast
}
}
As noted before: Once you need access to the generic type outside of the class thats implementing the IBuilder<T>
you'd need to start differentiating types and cast them accordingly. Not so elegant.
But you can design lot's of stuff this way and maintain extensibility. I bring this up, as I have used this pattern to implement image filters myself and your BuildCollagePattern
might be very much realizable with this design pattern.