据我所知,如果我们处理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
都相同?
答案 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只需要几纳秒。