Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a name for this pattern of using generics?

//this class (or interface if you like) is set up as generic...
public abstract class GenericBase<T> 
{
    public T PerformBasicTask(T in) { ... }
}

//... but is intended to be inherited by objects that close the generic...
public class ConcreteForDates:GenericBase<DateTime>
{
    public DateTime PerformSpecificTask(DateTime in) { ... }
}

//... so that consuming code never knows that a generic is involved
var myDateConcrete = new ConcreteForDates(); //look ma, no GTP!
//These two methods look alike, and there is no generic type inference,
//even with PerformBasicTask().
var basicResult = myDateConcrete.PerformBasicTask(DateTime.Now);
var specificResult = myDateConcrete.PerformSpecificTask(DateTime.Today);

//does not compile because T is understood by inheritance to be a DateTime,
//even though PerformBasicTask()'s implementation may well handle an int.
var anotherBasicResult = myDateConcrete.PerformBasicTask(1);

I've seen and used this pattern several times, and it's very useful for providing common functionality across a series of type-specific subclasses. For instance, this could be a model for Controllers/Presenters specific to a type of domain object that is central to the page(s) the class is used to control; basic operations like retrieval/persistence may use 100% common functionality, but binding/unbinding may be very specific.

Is there a name for this pattern of generic declaration without exposing the generic to the end user?

like image 360
KeithS Avatar asked Oct 31 '11 16:10

KeithS


3 Answers

I believe this is not a pattern but specifics of Generic Type subsystem of the .NET Framework which generates concrete type in runtime by substituting generic type parameter by a concrete type (in your example DateTime). All other things regarding sharing a common behaviour is known as Inheritance

like image 191
sll Avatar answered Nov 04 '22 23:11

sll


If I were to name it, I would call it Specifics and I agree with Aliostad in that it is an anti-pattern.

like image 33
Austin Salonen Avatar answered Nov 04 '22 22:11

Austin Salonen


Generics is used to re-use a behaviour that needs to be described beyond the type - or at least within the restrictions enforced by the where clause.

The example you have seen, IMHO, is a generics anti-pattern. Type should not matter or if it does, should only matter if it is defined in the restrictions - i.e. where clause.

So basically, a generic abstract class which expects all subclasses to implement an abstract, is not using the genericness. I cannot just simply start using Generic<MyType> which is the point of generics.

I believe that defeats the point.

In this case there is a slight benefit in using a generic abstract class/interface and that is type safety achieve for PerformSpecificTask.


UPDATE

I knew it is a contentious issue and I would be fired at left and right, but I believe it is the case.

A class can happily subclass a generic class and add more functionality. But in this case, it is the extra functionality that defines the identity of that class. When I cannot just say Generic<MyOwnTypeOfVolition> then I have defeated the objective of generics. Sometimes, however, it is not the generics which I am concerned with - it is the interface which seems to be the case here.


UPDATE 2

A classic example, is IConvertible in .NET Framework.

You could setup a generic interface/abstract class for it and ask all subclasses to implement it, but the framework makes it an optional case and supports it only for classes implementing the interface.

like image 28
Aliostad Avatar answered Nov 05 '22 00:11

Aliostad