It is also helpful when you have a series of classes to write and you realize that 80% (pick a number) of the code is essentially the same except it varies by TYPE.
Writing a generic allows you to capture all that repetitive code in a base class and reuse it.
The specific pattern above is important/necessary because you want the T to be the class you are trying to write.
Imagine a framework where the crud object is based on crudBase and everything inherits from that.
Imagine further that you have a base class that helps you query those objects (queryBase) and there will be a 1:1 with crudBase and queryBase classes.
Making queryBase a generic is simple because its fairly obvious how you would declare it
public abstract class queryBase<T> where T : crudBase
{
public list<T> FindMatches(string SearchCriteria){}
}
Without a generic, this would have to be in each concrete class because the return type changes. Generics are awesome.
what is a little less obvious is how to accomplish that same level of GENERIC nirvana with crudBase.
Assume you have 70% of the boiler plate CRUD code already in a subclass, but there is another 10% where the logic needs to reference the type.
(pick a number, the % numbers are not important)
The GENERIC solution is less obvious here. In the first case you GENERIC class is referencing a different class with T. In this case, you want to reference the same class with T.
using the pattern described above you can in fact achieve this :
public class crudBaseGeneric<T> where T : crudBaseGeneric<T>
{
public <T> CopyMe(){}
}
Here you will redefine your base class as a generic and you will be able to capture that last 10%.
Again, without generics, I have to copy paste my CopyMe() function in each concrete class.