Assume I have a static generic class. Its generic type parameters are not available until runtime. How to invoke its members?
Please see the following code snippet:
static class Utility<T>
{
public static void DoSomething() { }
}
class Tester
{
static Type GetTypeAtRuntime()
{
// return an object of type Type at runtime.
}
static void Main(string[] args)
{
Type t = GetTypeAtRuntime();
// I want to invoke Utility<>.DoSomething() here. How to do this?
}
}
Edit:
OK, this is the solution based on the responses given by two guys below. Thanks for both of you!
static class Utility<T>
{
//Trivial method
public static void DoSomething(T t) { Console.WriteLine(t.GetType()); }
}
// assume Foo is unknown at compile time.
class Foo { }
class Tester
{
static void Main(string[] args)
{
Type t = typeof(Foo);// assume Foo is u开发者_如何学JAVAnknown at compile time.
Type genType = typeof(Utility<>);
Type con = genType.MakeGenericType(new Type[] { t });
MethodInfo mi = con.GetMethod("DoSomething", BindingFlags.Static | BindingFlags.Public);
mi.Invoke(null, new object[] { Activator.CreateInstance(t) });
}
}
Then you'll need to use reflection to get the method and invoke it. Generic type arguments needs to be resolved compile time if you are going to declare an object of that type:
Type t= GetTypeAtRuntime();;
var doSomething = typeof(List<>).MakeGenericType(t).GetMethod("DoSomething", BindingFlags.Static | BindingFlags.Public);
doSomething.Invoke(null, new object[] { });
However in your example T is not used in the method signature or implementation and if that's the case I'd move it to a non-generic base class.
DISCLAIMER: the suggested solution is only meant as a you can do this if you really want to but from the example it seems mpore like an issue of the design. I'd suggest revisiting the use of static/generic in this case
You can use MakeGenericType to create the actual type and then use reflection to invoke the method. For example,
static void Main(string[] args)
{
Type t = GetTypeAtRuntime();
Type genType = typeof(Utility<>);
Type constructed = genType.MakeGenericType(new Type[] { t });
// Now use reflection to invoke the method on constructed type
MethodInfo mi = constructed.GetMethod("DoSomething", BindingFlags.Static);
mi.Invoke(null, null);
精彩评论