3

据我所知,如果我们在处理COM接口,任何简单的转换通常都会触发QueryInterface例程,该例程用于确定对象是否实际实现了相应的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从无类型object实例中获取相应的内容。

  • 但是,对于泛型,我想,一切都应该在没有强制转换的情况下完成,但我实际上并不确定它们在表面下是如何工作的。

  • 是否有可能List<T>仍然以某种方式对object类型进行操作(因此,将QueryInterface在所描述的场景中调用基于 - 的演员表)?

  • 如果上一个问题的答案是“否”,那么是否真的不能保证任何可能的情况都一样IList<T>

4

2 回答 2

2

您可以将泛型类型实例(例如List<IComInterface>)视为从泛型类型定义(例如List<T>)创建的类,方法是用 name 逐字替换Tname IComInterface。类型不会像在某些语言(最显着的是 Java)中那样被“擦除”,它与泛型类型实例一起保存,因此T在泛型类型定义中声明为类型的所有变量在泛型类型中保持强类型实例。

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

dynamic comInteface = ...
list.Add(comInteface); // There will be an implicit cast here
于 2012-07-12T12:28:16.030 回答
1

是的,这是一个相当不错的保证,除非必须,否则编译器不会发出 Opcodes.Castclass IL 指令。类型匹配,因此不需要强制转换。

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

于 2012-07-12T12:32:42.580 回答