C#:在运行时获取类型参数以传递到泛型方法中

19
通用方法是指...
    public void PrintGeneric2<T>(T test) where T : ITest
    {
        Console.WriteLine("Generic : " + test.myvar);
    }

我正从Main()函数调用这个东西...

    Type t = test2.GetType();       
    PrintGeneric2<t>(test2);

我遇到了错误 "CS0246: 无法找到类型或命名空间名称为 't'" 和 "CS1502: 最佳重载方法匹配 DoSomethingClass.PrintGeneric2< t >(T) 具有无效参数"。
这与我之前在这里提出的问题有关:C# : Passing a Generic Object
我已经阅读过,泛型类型不能在运行时确定,除非使用反射或方法信息,但我不太清楚如何在这种情况下做到这一点。
如果您能给我指点迷津,我将不胜感激 =)
3个回答

32

如果您真的想要在编译时不知道类型参数的情况下调用通用方法,可以编写类似于以下内容的代码:

typeof(YourType)
    .GetMethod("PrintGeneric2")
    .MakeGenericMethod(t)
    .Invoke(instance, new object[] { test2 } );

然而,正如其他答复中所述,泛型可能不是您的最佳解决方案。

这是一个非常好的示例,展示了如何在运行时类型下调用通用方法,但实际上OP并没有在他的示例中尝试这样做。@Moo-Juice的答案正确解决了OP的问题。尽管如此,我还是点赞了,因为每当我需要将“运行时类型作为通用参数”的情况时,我都会多次遇到这个答案。;) - JMD

8

泛型提供编译时参数化多态性。你试图在运行时只指定类型来使用它们。 简短回答:这不起作用,也没有理由这样做(除了反射,但那是完全不同的东西)。


2

只需调用:

PrintGeneric2(test2);

编译器将从您传递的内容中推断出<t>

1
您的建议将强制编译器将T推断为System.Type。我认为这不会正确地反映出OP传递运行时评估类型的意图。 - Adrian Zanescu
@AZ,不会的。完全忽略 Type t = test2.GetType() 部分,这里不需要。test2 实现了 ITest(请参见他之前的问题)。直接传递 test2 即可。 - Moo-Juice
好的。我没有检查另一个问题,所以我缺乏对test2的上下文理解。我仍然坚持我的假设,即OP希望在运行时以某种方式动态解决T,而这不是泛型的用途。 - Adrian Zanescu
2
@AZ,我认为他认为他需要动态解决它,但实际上他不需要。 :) - Moo-Juice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接