在C#中将Type对象用作泛型的类型参数

8

我无法找到一种方法,在C# 3.0 / .NET 3.5中将一流的Type对象(System.Type实例)用作通用构造中的类型参数。以下是我想要做的简化示例:

public void test()
{
    Type someType = getSomeType(); // get some System.Type object

    MyGeneric<someType> obj = new MyGeneric<someType>();  // won't compile
}

有没有办法将someType对象用作泛型的类型参数?


我个人使用了一个Switch。这可能并不适用于所有情况...我希望它能像你的例子一样。 - Camilo Martin
2个回答

17

你可以动态创建一个类型的实例:

public void test()
{
    Type someType = getSomeType(); // get some System.Type object
    Type openType = typeof(MyGeneric<>);
    Type actualType = openType.MakeGenericType(new Type[] { someType });
    object obj = Activator.CreateInstance(actualType);
}

然而,您无法声明此类型的变量,因为您静态地不知道实际类型。


如果有人看到这篇文章,在C# 4.0中,动态关键字允许您声明变量,其中禁用了编译时类型检查。 - Jacob Bundgaard
@JacobBundgaard,是的,但这与OP的问题无关。它不允许您在编译时不知道类型参数的情况下创建通用类型的实例。 - Thomas Levesque
我认为不是这样的。动态声明将允许您通过反射调用MyGeneric对象的方法,而对象声明则不会。考虑到MyGeneric有一个名为MyMethod的方法。那么这段代码将无法工作:object obj = Activator.CreateInstance(actualType); obj.MyMethod();,而这段代码将可以:dynamic obj = Activator.CreateInstance(actualType); obj.MyMethod(); - Jacob Bundgaard
如果我似乎在试图解决OP的问题,我很抱歉。现在四年过去了,OP可能已经超越了这个问题,而路过的人可能会受益于了解与该问题相关的新语言特性。 - Jacob Bundgaard

9

您希望在运行时确定类型参数。.Net泛型要求在编译时就知道类型参数。除了根据类型切换之外,实际上没有其他方法。您可以通过反射获取到方法的句柄并调用它,但这样做比较丑陋。


3
托马斯展示了如何做,但你更好地解释了为什么需要反射。 - Andrew Hare

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