The problem is it's resolving T
to the compile time type of where you're calling the method. In this case, it's being called/resolved from within Foo.Something
and the compile-time type of this
is Foo
, not Bar
.
One option is to make the call virtual
and have each type override
it. This will make each time provide compile-time type information when calling the method:
public class Foo
{
public virtual void DoSomething()
{
DoSomething(this);
}
//notice this is protected now so it's accessible to `Bar`
protected static void DoSomething<T>(T obj)
{
var generic = new Generic<T>();
}
}
public class Bar : Foo
{
public override void DoSomething()
{
DoSomething(this);
}
}
Another option is to use the Dynamic Language Runtime to have it resolve the type at runtime:
public class Foo
{
public void DoSomething()
{
dynamic thisDynamic = this;
DoSomething(thisDynamic);
}
private static void DoSomething<T>(T obj)
{
var generic = new Generic<T>();
}
}
EDIT: If you're not using .NET 4.0 and don't have access to the Dynamic Language Runtime, you can employ generics as well:
public class Foo
{
public void DoSomething()
{
DoSomething(this);
}
private static void DoSomething(object obj)
{
Type runtimeType = obj.GetType();
MethodInfo createMethod = typeof(Foo).GetMethod("CreateGeneric", BindingFlags.Static | BindingFlags.NonPublic);
var genericCreateMethod = createMethod.MakeGenericMethod(runtimeType);
genericCreateMethod.Invoke(null, new[]{obj});
}
private static void CreateGeneric<T>(T obj)
{
var generic = new Generic<T>();
}
}
Note that I'm assuming you need the T obj
parameter in the CreateGeneric
method. If you don't actually need it, you can update the method signature and calling reflection code to omit it.