I am reading existing posts on Generics at SO. If Generics has so many advantages like Type safety, no overhead of boxing/unboxing and it is fast, why not always use it? Why
Generics is the way to go generally. Added complexity could be one argument against it, but imo it's totally worth considering the benefits in most cases. As a general rule of thumb, embrace it. Reflection is another case which generics makes it harder. But I avoid generics only if it doesn't make sense.
The one scenario where I like to avoid generics is making a method generic when it serves no intended purpose of generics and can be misleading. Generics was introduced for better type safety and performance (when it comes to value types). If it serves neither, then a generic approach can be misleading to developer. For example consider the snippet from this question:
public void DoSomething(T request)
{
if (request == null)
throw new ArgumentNullException("request");
if (request is ISomeInterface)
DoSomething();
else
DoSomethingElse();
}
There is nothing generically handled in the above method. Its even worse when you do a lot of type checking in a generic method:
public void DoSomething(T request)
{
if (typeof(T) == typeof(X))
DoSomething();
else if (typeof(T) == typeof(Y))
DoSomethingElse();
...
}
which completely defeats the logic of generics. There are better patterns to avoid type checking, but if it is absolutely necessary, then accepting object
as parameter is what I would prefer. Another similar case is when value types are anyway boxed in a generic method:
public void DoSomething(T request)
{
var type = request.GetType(); //boxed already in case of value types.
//or other reflection calls which involves boxing
}
By seeing the method definition one is tempted to think of this method not having boxing penalties, but letting the caller know it clearly is one good way. I like it like:
public void DoSomething(object request) //boxes here
{
var type = request.GetType();
//or other reflection calls which involves boxing
}
Other than that, I prefer generics all the time.
An edge case where the two could behave differently is with dynamic
.
public void Generic(T request)
{
}
public void Object(object request)
{
}
dynamic d = null;
Object(d); //no issues
Generic(d); //run-time explosion; can not infer type argument
Not a factor to consider, just a silly difference in behaviour worth having in mind.