【问题标题】:How are interface types loaded by the CLR?CLR 如何加载接口类型?
【发布时间】:2015-10-31 16:46:22
【问题描述】:

如果接口类型未使用具体实现进行初始化,CLR 是否会加载它们?

考虑具有实现 FooImpl 的接口 IFoo

例如

IFoo foo;

相对于

IFoo foo = new FooImpl();

CLR 只会在第二种情况下加载 IFoo 类型吗?此外,如果存在从 FooImpl 继承的另一种类型(例如 FooImpl2)

这段代码是否会从 FooImpl2 开始并沿着继承层次结构加载 IFoo 接口?此外,IFoo 的 MethodTable 是否会包含直接指向 FooImpl2 的方法表的指针,还是会通过中间实现类型(即 FooImpl)重定向。

IFoo foo = new FooImpl2();

【问题讨论】:

  • 没有什么非常微妙的事情发生,CLR 中的存根是一座 99% 都在水下的冰山。 Vance Morrison 在this blog post 中解释得很好。
  • @HansPassant 感谢分享帖子,会通过它!我记得你曾在 2009 年主持过 MSDN 论坛……

标签: c# .net interface clr method-dispatch


【解决方案1】:

这行代码

IFoo foo;

表示foo 是一个变量,可以保存对实现接口IFoo 的对象的引用。

CLR 只会在第二种情况下加载 IFoo 类型吗?

在第二种情况下,您创建一个FooImpl 类型的对象,并使用一个名为foo 的变量来存储对该对象的引用。为了让变量持有对对象的引用,变量的类型应该符合该对象。说兼容,我的意思是变量的类型与您创建的对象相同,或者是基本类型或接口。话虽如此,没有任何界面的负载。

这行代码:

IFoo foo = new FooImpl();

表示foo 将持有对实现IFoo 接口的对象的引用,仅此而已。

此外,如果存在从 FooImpl 继承的另一种类型(例如 FooImpl2) 这段代码是否会从 FooImpl2 开始并沿 继承层次结构来加载 IFoo 接口?

没有

另外,IFoo 的 MethodTable 是否包含一个直接指向 FooImpl2的方法表还是会通过中间重定向 实现类型(即 FooImpl)。

将存储在变量中的引用将指向 FooImpl2 的方法表直接。实际上,它会指向存储在堆中的具体对象,并且会引用FooImpl2的方法表。

【讨论】:

  • 感谢您的回答,在 IFoo foo = new FooImpl2 的情况下,CLR 是否看到 IFoo 类型,然后使用 SlotMap 将调用重定向到实际实现。还是 CLR 看到的是 FooImpl2 的对象而不是接口?
  • @ganeshran 欢迎您!我很高兴我帮助了:)。 CLR 确实看到了一个引用分配。您可以分配给左操作数的应该实现IFoo 类型。只是这个。顺便说一下,关于这个主题的最详细的书是 Jeffrey 的 Richter,CLR via C#,amazon.com/CLR-via-Edition-Developer-Reference/dp/0735667454
猜你喜欢
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 2017-03-09
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多