使用Activator <t> .CreateInstance()按运行时类型信息创建类型

时间:2016-11-17 17:36:43

标签: c# dynamic reflection

简介

要通过反射动态创建实例,我们可以使用:

Activator.CreateInstance 

这样做的缺点是这会返回一个object,而我真的需要具体类型,因为我只知道我无法投射的运行时类型。

为实现这一目标,我们可以使用

Activator.CreateInstance<T>

返回T,但由于我在编译时不知道T,因此也没有用。无论如何乍一看。

目前,我以一种特殊的方式使用dynamic

//I pass the runTimeType as an ITopSecret

// runTimeType implements ITopSecret
dynamic concreteTypeInstance = Activator.CreateInstance(runTimeType);

// Now we just have an empty RunTimeType. 
// I can use the passed runTimeType to fill the newly created object
concreteTypeInstance = runTimeType

// Then I call ApplyCurrentValues.
// Can't pass runTimeType, because it's ITopSecret and
// EF doesn't figure out the actual runtime type.
context.ApplyCurrentValues(concreteTypeInstance)

在此行之前,会执行一些健全性检查。例如,我知道此时运行时类型始终是某个ITopSecret,否则该语句不会被命中。

所以这可能是相当安全的。它完全符合我的要求,有一行代码,看起来很棒。

但是,我不确定这是否是使用dynamic的预期方式,以及我是否会为讨厌的东西打开门。

为什么我要这个

目前,我们在各种服务的许多Update方法中都有1000多行样板代码。这是手工制作的,因此容易出错,具有重复性,违反DRY并使新人更难。 此外,这使得方法不清楚,因为他们不再关注业务逻辑,坦率地说,这只是简单的丑陋。所有常见的嫌疑人;)

所以我写了一些抽象/通用代码来分解所有重复的东西。这是一个非常好的和很酷的软件编写,但留给我(主要)运行时信息。

在表面下,这些方法都使用Entity Framework及其ApplyCurrentValues方法。这种方法需要具体的,实例化的类型,因此需要我的问题。

希望这很清楚:)

问题

  • 这是一种使用dynamic的好方法,考虑到我在实际使用之前执行了一些健全性检查吗?
  • 我觉得有一种方法可以用反射来实现这一目标。在性能方面可能会更糟,但如果能做到这一点,我会很好奇。 是否可以使用反射创建通用Activator.CreateInstance<T>
  • 两种可能性都不好,我应该采取完全不同的方法吗? 然而,不知道运行时的具体类型,但无论如何都需要它们不是我可以摆脱的东西。

0 个答案:

没有答案