【问题标题】:Get a new object instance from a Type and access it as such at compile-time从 Type 获取新的对象实例并在编译时访问它
【发布时间】:2015-02-03 09:17:31
【问题描述】:

现在,在你们都急于告诉我这个问题已经在其他地方得到回答之前here,例如here,让我说它只是部分得到了回答,至少据我所知。

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

var inst = Activator.CreateInstance(t);

但是,instobject 上,我希望它是 t 类型。以下都不合法:

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

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

【问题讨论】:

  • "我如何在编译时获得我想要的类型?" - 出于什么目的?你到底想用这个做什么?如果您告诉我们您想要达到的目标,我想我们可以就适当的方式提供建议。
  • @MarcGravell,我需要能够将inst 作为类型化参数传递给另一个方法。
  • 单一方法?还是一系列具有不同类型参数的重载?如果是单一方法:只需转换它 - Foo(123, "abc", (SomeType)inst);;如果是一系列重载:dynamic 可能会有所帮助 - 但这是一个 hack
  • 本质上,这将是基于类型本身的多种不同方法之一。
  • 然后是 reflection(手动选择并调用该方法)或 dynamic。后者基本上是前者的自动化方式。 Foo(123, "abc", (dynamic)inst); 将调用它可以找到的最合适的方法(如果找不到合适的方法,则会出错)

标签: c#


【解决方案1】:

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

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


从 cmets 看来,这里的预期用途是用于方法重载解析; 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);

将尝试基于instruntime 类型调用最合适的 Foo 重载,并使用每种类型的缓存优化等。有点一个 hack,但它有效,并且比手动检查更容易和更干净(并且由于策略缓存,通常也更有效)。

如果您对inst 所做的唯一 事情是将其向前传递,您可以将inst 本身设为dynamic

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

请注意,您一般应该对此保持谨慎,但是,一旦变量为dynamicall 对它的访问是通过dynamic API - 即使是对采用object 参数(例如string.Format)的方法的调用也将通过运行时而不是编译器进行路由(当然,除非您明确地将其转换回object 或类似的)。

【讨论】:

  • 这是否允许我将结果作为类型参数传递?
  • @StuartHemming 需要更多上下文;请参阅我对问题的评论(回复您的评论)
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 2021-07-10
  • 2014-05-23
  • 2022-07-27
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多