37

While reviewing some code, I noticed the opportunity to change it to use generics. The (obfuscated) code looks like:

public void DoAllTheThings(Type typeOfTarget, object[] possibleTargets)
{
    var someProperty = typeOfTarget.GetProperty(possibleTargets[0]);
    ...
}

This code could be replaced by generics, like so:

public void DoAllTheThings<T>(object[] possibleTargets[0])
{
    var someProperty = type(T).getProperty(possibleTargets[0]);
    ...
}

In researching the benefits and shortcomings of this approach I found a term called generic abuse. See:

My question comes in two parts:

  1. Are there any benefits to moving to generics like this? (Performance? Readability?)
  2. What is Generics Abuse? And is using a generic every time there is a type parameter an abuse?
SyntaxRules
  • 581
  • 1
  • 4
  • 13

4 Answers4

88

When generics are appropriately applied, they remove code instead of just rearranging it. Primarily, the code that generics are best at removing is typecasts, reflection, and dynamic typing. Therefore generics abuse could be loosely defined as creating generic code without significant reduction in typecasting, reflection, or dynamic typing compared to a non-generic implementation.

In regard to your example, I would expect an appropriate use of generics to change the object[] to a T[] or similar, and avoid Type or type altogether. That might require significant refactoring elsewhere, but if using generics is appropriate in this case, it should end up simpler overall when you're done.

Robert Harvey
  • 200,592
Karl Bielefeldt
  • 148,830
5

I would use the no-nonsense rule: Generics, like all other programming constructs, exist to solve a problem. If there is no problem to solve for generics, using them is abuse.

In the specific case of generics, they mostly exist to abstract away from concrete types, allowing code implementations for the different types to be folded together into one generic template (or whatever your language happens to call it). Now, suppose you have code that uses a type Foo. You might replace that type with a generic T, but if you only ever need that code to work with Foo, there is simply no other code with which you can fold it together. Thus, no problem exists to be solved, so the indirection of adding the generic would just serve to reduce readability.

Consequently, I'd suggest to just write the code without using generics, until you see a need to introduce them (because you need a second instantiation). Then, and only then, is the time to refactor the code to use generics. Any use before that point is abuse in my eyes.


This seems to sound a bit too pedantic, so let me remind you:
There is no rule without exceptions in programming. This rule included.

0

The code looks odd. But if we are calling it, it looks nicer to specify the type as a generic.

https://stackoverflow.com/questions/10955579/passing-just-a-type-as-a-parameter-in-c-sharp

Personally I don't like these contortions that make the calling code look pretty. for example the whole 'fluent' thing and Extension Methods.

But you have to admit that it has a popular following. even microsoft use it in unity for example

container.RegisterType<IInterface,Concrete>()
Ewan
  • 83,178
0

To me it looks like you were on the right path here, but didn't finish the job.

Have you considered changing the object[] parameter to Func<T,object>[] for the next step?

sq33G
  • 278