What are the situations and their associated benefits of using Generics over Inheritance and vice-versa, and how should they be best combined?
Thanks for the answer
Use generics to specify an algorithm or type's behaviour which can be expressed in terms of some "unknown type" while keeping an API which is strongly typed in terms of that unknown type. The unknown type is known as a type parameter and is expressed in the code like this:
public class List<T>
{
public void Add(T item)
}
(etc) - here T
is the type parameter. Generic methods are similar:
public void Foo<T>(T item)
The calling code specifies the type argument it wants to work with, e.g.
List<string> list = new List<string>();
list.Add("hi");
Use inheritance to specialize the behaviour of a type.
I can't really think of many places where they're alternatives to each other...
They're really different ideas altogether. Generics allow you to declare common "specific" functionality (at the risk of sounding oxymoronic) in a general way. A List<int>
doesn't function any differently from a List<string>
, aside from the type of data that is held inside.
While inheritance could be used to do the same thing, I could create a List
class, then an IntList
and a StringList
class that inherit from it. I could easily make these two classes function entirely differently, or have one offer functionality not available in the other one.
Edit
After reviewing the edit to the question, the answer sortof is "it depends." You can make arguments for both sides--and, indeed, LINQ to SQL and the Entity Framework are both a combination of both reflective inspection using generics, and strongly-typed entity classes and other repository classes. You can certainly take the approach that you're looking at, just know that, in general, a problem that can be solved either with reflection or with something else is LIKELY going to be faster when solved by the "something else." It comes down to how much of a tradeoff you want among performance, maintainability, readability, and reliability.
Inheritance is much more about "is-a" (frog is an animal) where generics is about creating containers that act on typed data (List of T, Processor of T, etc). They are not mutually exclusive.
You can have this if you want:
public class Base<T>
{
}
public class Derived : Base<Foo>
{
}
You should use generics when you want only the same functionality applied to various types (Add, Remove, Count) and it will be implemented the same way. Inheritance is when you need the same functionality (GetResponse) but want it to be implemented different ways.
Use generics when you want to create a "template" that can apply to many styles of unknown classes. Eg. Collections holding ??? are good candidates for generics. Inheritance is for when you have a base conecpt that children "are" an extension of that concept.
My general rules
Neither inheritance nor parameterized types can change at run-time
Inheritance lets you provide default implementations for operations and lets subclasses override them.
Parameterized types let you change the types that a class can use.
But Which approach is best depends on your design and implementation constraints
Design Patterns Elements of Reusable Object-Oriented Software