views:

159

answers:

4

I'd like to add a generic type method DoSomething<T>, but for backwards compatibility, I want it to simply pass the type parameter for the generic type from an existing method with the same name.

public void DoSomething<T>(Data data)
{
    //do something with Data, it depends on the type of T
}

public void DoSomething(Data data, Type dataType)
{
    DoSomething<dataType>(group);
}

However, <dataType> in the new DoSomething throws following type checking error: "Type name or namespace expected."

Can someone help me understand the gap in my thinking that makes the above sample a type checking error? Is what I'm doing just... bad design?

+1  A: 

If this is a private method, what concern is there for external backwards compatibility?

yankee2905
sample updated.
Mike Atlas
+5  A: 

I generally find it easier to reverse the relationship between the methods, i.e.:

private void DoSomething<T>(Data data)
{
    DoSomething(data, typeof(T));
}

private void DoSomething(Data data, Type dataType)
{
    ...
}
Michael Morton
Yes, this is what you have to do.
erikkallen
+12  A: 

Generics is about knowing the type at compile-time - you only know the type at execution time.

There are two ways of fixing this:

  • Make the generic code call the non-generic code instead. That's easy, but you won't have any of the benefits of generics.

  • Use reflection to call the generic code from the non-generic code. That's fiddly and won't perform as well, but you can deprecate the non-generic code and eventually remove it.

Or you could just remove it now, and fix everything up :)

Jon Skeet
If it's really an issue; with some compiled lambda expressions you can get this quite fast as well :-)
Jan Jongboom
The fact that Generics wire up at compile-time is what I was missing when I tried to write code that looked like Mike Atlas' example.
jball
+5  A: 

The problem here is that you are mixing generic argument and runtime type information. The type values used for a generic arguments must be established at compile time and are embedded in metadata. The type Type is a construct whose value is not known at compile time. Hence the 2 are not compatible.

Your best bet here is to make the original DoSomething method the primary method and have the new generic one feed into it.

static void DoSomething<T>(Data data) {
  DoSomething(data, typeof(T));
}

static void DoSomething(Data data, Type dataType) {
  ...
}
JaredPar