tags:

views:

83

answers:

3

Is there ever a reason to use Type parameters over generics, ie:

// this...
void Foo(Type T);
// ...over this.
void Foo<T>();

It seems to me that generics are far more useful in that they provide generic constraints and with C# 4.0, contravarience and covarience, as well as probably some other features I don't know about. It would seem to me that the generic form has all the pluses, and no negatives that the first doesn't also share. So, are there any cases where you'd use the first instead?

+5  A: 

Absolutely: when you don't know the type until execution time. For example:

foreach (Type t in someAssembly.GetTypes())
{
    Foo(t);
}

Doing that when Foo is generic is a pain in the butt. It's doable, but painful.

It also allows the parameter to be null, which can be helpful in some situations.

Jon Skeet
It's also alot more expensive and slow to do with generics (all those reflection calls can't be pretty)
Matthew Scharley
Absolutely - although the pain is normally more important to me :)
Jon Skeet
A: 

Well they really aren't the same at all.

With the second one, you've actually got a class of the compile-time type there (whatever has been passed in by whoever). So you can call specific functions on it (say if it's all of some given interface).

In your first example, you've got an object of class 'Type'. So you'll need to still determine what it is and do a cast to do anything useful with it.

Noon Silk
Exactly, the second form has all the benefits of compile-time checking. So given that, among other things, I wanted to know if there was ever a reason to use the first. I realise they are different, but different doesn't mean that one form doesn't completely subsume the need for the other.
Matthew Scharley
Well my point is you'll use the first for a totally different purpose than the second. You'd never use them for the same thing (i.e: calling common methods or performing 'generic' actions on a given class type).
Noon Silk
A: 
Foo(someVariable.GetType());      // allowed

Foo<someVariable.GetType()>();    // illegal
LukeH
I believe that was Jon's point.
Matthew Scharley