Reputation: 1819
In the following code, I'd like to call a method that I declared in the derived class:
class BaseClass
{
// ...
}
class A<T> : BaseClass
{
public void F(T args){ //... }
}
class B<T> : BaseClass
{
// B<T> doesn't have method F()
}
///....
class myApplication
{
// ...
public void DoSomething(BaseClass arg)
{
// Now I know that arg is of type A<T> for some type T
// but I don't know what T is. Also declaring DoSomething
// as DoSomething<T>() is not an option.
//
// I would like to call (arg as A<T>).F(...) but how can I
// deduce T? Can it be done in any other way?
}
}
Please read the comment in the code. How can I do something like this?
Upvotes: 1
Views: 57
Reputation: 22421
In order to call the method, you can run the following code:
class myApplication
{
// ...
public void DoSomething(BaseClass arg)
{
var type = arg.GetType();
// Check whether a generic type was passed
if (type.IsGenericType)
{
var genType = type.GetGenericTypeDefinition();
// Check whether it is of type A<>
if (genType == typeof(A<>))
{
// Get generic argument type
var genArg = type.GenericTypeArguments[0];
// Create a default instance; might not work under all circumstances
// Better to get the method parameter in another way
var mthArg = Activator.CreateInstance(genArg);
// Get method that is to be called
var mth = type.GetMethod("F");
// Invoke method dynamically
mth.Invoke(arg, new object[] { mthArg });
}
}
}
}
Please note that it is important to pass an argument of type T
to method F
. You have to prepare the value for this. In my sample, I've added a call to Activator.CreateInstance that requires T to have a public default constructor (I've used int
for testing).
Upvotes: 2