如果泛型类型参数在运行时之前是未知的,如何调用静态泛型类方法?

时间:2010-10-08 08:25:52

标签: c#

假设我有一个静态泛型类。 其泛型类型参数在运行时才可用。 如何调用其成员?

请参阅以下代码段:

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?

    }
}

编辑:

好的,这是基于下面两个人给出的答案的解决方案。谢谢你们俩!

 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 unknown 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) });

    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用MakeGenericType创建实际类型,然后使用反射来调用该方法。 例如,

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);

答案 1 :(得分:2)

然后你需要使用反射来获取方法并调用它。如果要声明该类型的对象,则需要在编译时解析泛型类型参数:

Type t= GetTypeAtRuntime();;
var doSomething = typeof(List<>).MakeGenericType(t).GetMethod("DoSomething", BindingFlags.Static | BindingFlags.Public);
doSomething.Invoke(null, new object[] { });

但是在您的示例中,T未在方法签名或实现中使用,如果是这种情况,我会将其移动到非泛型基类。

免责声明:建议的解决方案只是意味着你可以这样做,如果你真的想要,但从例子看起来似乎就像设计的问题。我建议在这种情况下重新使用static / generic