C# - <t>对象转换</t>

时间:2012-07-12 12:14:20

标签: c# com casting queryinterface

据我所知,如果我们处理COM接口,任何简单的转换通常会触发QueryInterface例程,该例程用于确定对象是否实际实现了相应的{{ 1}} interface。

COM

因此,以下代码(取决于编译器和优化)可能会在内部对象强制实现中触发 object whatever; IComInterface casted = (IComInterface) whatever;

QueryInterface

问:

假设我有一个通用的IComInterface comInteface; // I guess nothing COM-related happens here, but I might be wrong object whatever = comInteface; // This might or might not trigger the 'QueryInterface' call. IComInterface comInterface2 = (IComInteface) whatever; 实例:

List<T>

现在,我是否有强烈保证以下代码不会触发基于List<IComInterface> list = new List<IComInterface>(); 的演员表?

QueryInterface
  • 在此处使用List<IComInterface> list = new List<IComInterface>(); IComInterface comInterface = (...); // Somehow got it. list.Add(comInteface); IComInterface retrieved = list[0]; 代替ArrayList实际上会导致执行转换,因为您必须从无类List<T>实例中获取相应的IComInterface。< / p>

  • 但是,如果是仿制药,我想,一切都应该在没有铸造的情况下完成,但我不确定它们是如何在表面下工作的。

  • object是否仍然可以某种方式与List<T>类型一起运行(因此,将在所描述的场景中调用基于object的强制转换)?

  • 如果上一个问题的答案为“否”,是否属实,您不能保证对任何可能的QueryInterface都相同?

2 个答案:

答案 0 :(得分:2)

您可以将泛型类型实例(例如List<IComInterface>)视为从通用类型定义(例如List<T>)创建的类的字面意思将名称T替换为名称IComInterface。该类型不会像某些语言(最值得注意的是Java)那样“擦除”,它与泛型类型实例保持一致,因此在泛型类型定义中声明为类型T的所有变量都保持强在泛型类型实例中键入。

如果是List<IComInterface>,只要在编译时插入已知为object类型的对象,就不会转换为IComInterface。您的帖子的代码就是这种情况,但可能并非总是如此。例如,当您插入动态类型对象时,编译器将添加一个强制转换:

dynamic comInteface = ...
list.Add(comInteface); // There will be an implicit cast here

答案 1 :(得分:1)

是的,这是一个相当不错的保证,除非必须,否则编译器不会发出Opcodes.Castclass IL指令。类型匹配所以不需要演员。

这一般不应该关注你。 COM接口的QI实现由于COM内部的各种原因而受到重创。它总是非常快,比较一个guid只需要几纳秒。