向下转换的性能有何影响?

时间:2008-11-20 15:51:17

标签: generics c#-2.0

试着通过阅读this enlightening article by Juval Lowy

来了解Generics

释义..定义泛型类定义时,将其编译为IL。

  • 对于值类型,只要您请求特定的值类型,它就会用您的特定值类型替换T以获取该特定配置的IL,例如MyList<int> 好处:没有装箱和拆箱的处罚。
  • 对于引用类型,编译器替换了定义中的所有T实例,并创建了用于所有引用类型的IL。然而,实例是根据实际请求的ref类型分配的,例如MyList<String>

现在预先通用,我们可以编写采用Object参数的方法。泛型声称100%的性能提升是因为'它可以避免在您想要使用它时将对象类型向下转换为特定类型时产生的性能损失'

 // assume GetItem returns an Object
 string sMyPreciousString = (string) obList.GetItem(); 

当您从Object转发到特定引用类型时,这个性能会受到什么影响?此外,似乎向对象(甚至泛型会做到这一点)的向上投射不是性能打击..为什么?

3 个答案:

答案 0 :(得分:6)

向上转换到对象不需要执行时间检查 - 它总是有效,并且基本上只是一个无操作。

向下转换需要执行时间检查,以确保您没有将Stream转换为String。这是一个非常小的惩罚,并且不太可能成为瓶颈 - 但避免它只是泛型的一个额外好处。

答案 1 :(得分:1)

性能影响来自于运行时类型检查的需要。如果B是A的子类,那么当你将B转换成A时,你知道在编译时它是安全的,因为所有的B都是As。因此,您无需生成任何运行时代码来检查类型。

但是,当您将A转换为B时,您在编译时不知道A是否实际上是B。它可能只是一个A,它可能是C类型,是A的不同子类型。因此,您需要生成运行时代码,以确保该对象实际上是B并且如果不是则抛出异常。

泛型没有这个问题,因为编译器在编译时知道只有Bs被放入数据结构中,所以当你拿出一些东西时,编译器知道它将是B,所以没有需要在运行时进行类型检查。

答案 2 :(得分:1)

阅读生成的IL(这个article提到它)... aha - isinst。

如果您没有向下转发,则无需拨打isinst