【发布时间】:2012-07-12 12:14:19
【问题描述】:
据我所知,如果我们在处理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>实际上会执行强制转换,因为您必须从无类型的object实例中获取相应的IComInterface。但是,如果是泛型,我想,一切都应该在没有强制转换的情况下完成,但我实际上并不确定它们在表面下是如何工作的。
List<T>是否仍可能以某种方式与object类型一起运行(因此,将在所描述的场景中调用基于QueryInterface的强制转换)?如果上一个问题的答案是“否”,是不是就不能保证任何可能的
IList<T>都一样?
【问题讨论】:
-
据我所知,当您创建泛型类型时,我认为 .NET 创建了一个新类型的实例 - 因此强类型泛型不会使用
System.Object引用 - 我可能错了 -
我不是 100% 确定,所以写评论,一件事是如果你使用 List
不会发生转换,另一件事是你的第二个问题是不相关的,因为 List 实现了 IList . -
@GuruKara 第二个问题,正如我现在意识到的那样,是愚蠢的,因为有人可以实现
IList<T>,它使用object来存储数据,然后将其转换回:) 所以,我猜,这个问题只是关于List<T>。 -
这可能值得一读:artima.com/intv/generics2.html - 它似乎揭示了 IL 生成的内容以及 CLR 实际在做什么。听起来每个泛型类型都是单独处理的 - 给它一个阅读
-
有趣的是: Bruce Eckel:你只需要投射。 Anders Hejlsberg:不,实际上你没有。我们可以共享原生镜像,但它们实际上有单独的 VTable。我只是指出,我们在有意义的地方进行了相当积极的代码共享,但我们也非常注意不要在您想要的性能上共享。通常对于值类型,您确实关心 List
是 int。您不希望它们被装箱为对象。装箱值类型是我们可以共享的一种方式,但天哪,这将是一种昂贵的方式。
标签: c# com casting queryinterface