从Type中获取一个新对象实例,并在编译时访问它

时间:2015-02-03 09:17:31

标签: c#

现在,在你们匆匆告诉我问题已在其他地方here,例如或here回答之前,请允许我说它只是部分回答,至少就我而言看到。

我有一个Type类型的变量,我想创建一个t代表的类型的实例,所以我称之为......

var inst = Activator.CreateInstance(t);

但是,inst位于object,我希望它属于t类型。以下任何一项都不合法:

t inst = Activator.CreateInstance(t);
var inst = (t)Activator.CreateInstance(t);
var inst = Activator.CreateInstance(t) as t;

我该怎么做?如何在编译时让inst成为我想要的类型?

1 个答案:

答案 0 :(得分:3)

这根本不可能。编译器是静态类型(除非它不是; p)。 t变量变量!= 静态。你想做什么是不可能的。

此处的一个选项是泛型,但仍然可以将其作为<T>获取,如果<T>仍然只知道相同的方法,则无效object。另一种选择是dynamic;这意味着inst.Foo();工作 - 但仅限于运行时,并且仅当类型确实具有Foo()方法时;重要的是,编译器仍然在编译时不会知道t的方法。


从评论中看来,这里的预期用法是用于方法重载解析; dynamic可以提供帮助 - 例如:

Foo(Customer cust) {...}
Foo(Order order) {...}
Foo(Region region) {...}

object inst = Activator.CreateInstance(t); // t probably one of the above types
...
Foo((dynamic)inst);

将尝试基于{em>运行时类型Foo调用最合适的 inst重载,并进行每类缓存优化等。它有点像黑客,但是它可以正常运行,并且比手动检查更简单,更清晰(并且由于策略缓存,通常也更有效)。

如果您使用inst进行的事件向前传递,您可以inst本身dynamic

dynamic inst = Activator.CreateInstance(t);
Foo(inst);

请注意,一般对此有点谨慎,但是,一旦变量为dynamic所有访问权限都是通过{ {1}} API - 即使对带有dynamic参数(例如object)的方法的调用也将通过运行时而不是编译器进行路由(除非您明确地将其转发回string.Format或类似的。)