使用Type对象创建泛型

时间:2010-03-29 20:50:14

标签: c# .net generics reflection

我正在尝试使用Type对象创建泛型类的实例。

基本上,我会在运行时拥有不同类型的对象集合,因为无法确定知道它们究竟属于哪种类型,我认为我必须使用Reflection。

我正在做类似的事情:

Type elType = Type.GetType(obj);
Type genType = typeof(GenericType<>).MakeGenericType(elType);
object obj = Activator.CreateInstance(genType);

哪个好,好。 ^ ___ ^

问题是,我想访问我的GenericType&lt;&gt;的方法。实例,我不能,因为它被键入为对象类。我找不到将obj转换为特定GenericType&lt;&gt;的方法,因为这首先是问题(即,我不能放入类似的东西)。

((GenericType<elType>)obj).MyMethod();

如何处理这个问题?

非常感谢! ^ ___ ^

7 个答案:

答案 0 :(得分:5)

您必须继续使用Reflection来调用实际方法:

// Your code
Type elType = Type.GetType(obj);
Type genType = typeof(GenericType<>).MakeGenericType(elType);
object obj = Activator.CreateInstance(genType);

// To execute the method
MethodInfo method = genType.GetMethod("MyMethod",
    BindingFlags.Instance | BindingFlags.Public);
method.Invoke(obj, null);

有关详细信息,请参阅Type.GetMethodMethodBase.Invoke

答案 1 :(得分:4)

一旦你开始反射游戏,你必须一直玩到最后。该类型在编译时是未知的,因此您无法强制转换它。您必须通过反射来调用该方法:

obj.GetType().InvokeMember(
    "MyMethod", 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, 
    null, 
    obj, 
    null
);

答案 2 :(得分:3)

在C#3.5中,您必须使用Type.GetMethodMethodInfo.Invoke来调用该方法。

在C#4中,您可以使用dynamic关键字并在运行时绑定到该方法。

答案 3 :(得分:2)

最直接的方法是从GenericType中提取非泛型超类型(基类或接口),其中包含您为此目的要公开的方法:

class GenericType<T> : GenericBase { ... }
class GenericBase { abstract void MyMethod(); }

如果失败,请使用反射来访问@Aaronaught建议的方法本身。

答案 4 :(得分:1)

创建实例后,只需执行以下操作:

MethodInfo method = genType.GetMethod("MyMethod");
method.Invoke(obj, null);

答案 5 :(得分:0)

如果你知道要调用的方法的签名,你不仅可以使用MethodInfo.Invoke(),如此处的其他示例所示,还可以创建一个委托,允许更有效的调用(如果你需要调用同样的方法多次使用Delegate.CreateDelegate()

答案 6 :(得分:0)

我不确定你的类型有多大变化,或者你是否可以控制你将在其中调用的方法,但是创建一个界面来定义你将要使用哪些函数可能会很有用打电话。因此,在创建实例后,您可以转换为接口并调用您需要的任何函数。

所以创建你的标准界面(如果你能控制它们,你需要在每种类型中实现):

interface IMyInterface
{
   void A();
   int  B();
}

class One : IMyInterface
{
   ...
   implement A and B
   ...
}

Type elType = Type.GetType(obj);
Type genType = typeof(GenericType<>).MakeGenericType(elType);
IMyInterface obj = (IMyInterface)Activator.CreateInstance(genType);
obj.A();