【问题标题】:Implications of using a class through an interface通过接口使用类的含义
【发布时间】:2013-02-15 11:48:42
【问题描述】:

通过接口使用类而不是直接使用类有什么含义?

例如,当通过IList<Int32> 接口而不是直接使用List<Int32> 类来改变整数列表时。这是否会引入装箱转换、更多类型检查、空值检查、更多间接级别、虚拟调用、减少优化、防止方法内联?如果是这样,我该如何减轻其中的一些影响?

我正在编写一个库,我打算在其中的所有集合类都通过它们的接口使用。该库适用于可能希望在高性能环境中使用它的其他开发人员。

【问题讨论】:

  • 如果您非常担心性能,为什么不使用数组而不是集合类
  • 所以你宁愿不知道,只是盲目地使用数组......这是一种方式。我并没有很担心,只是想知道这些问题。只有这样,才能在特定情况下做出良好的评估。
  • 因为信息是特定于 CLR 实现的,它可能会在未来的版本中发生变化,这不是 VM 的全部目的——抽象出你不应该依赖的细节
  • @Ankur:我不认为这是特定于实现的。 CLI 标准 (ECMA-335) 竭尽全力指定虚拟调度(virtualnewslot/reuseslotcall/callvirt 等)。

标签: c# class interface


【解决方案1】:

拳击

AFAIK,如果实现类型是引用(即class)类型,接口不会引入任何额外的装箱。如果实现类型本身是值类型(即struct),那么当分配给接口类型的变量时,该值类型将被装箱:

struct Foo : IFooBar { … }           class Bar : IFooBar { … }
IFooBar foo = new Foo();             IFooBar bar = new Bar();
//          ^                                    ^
//       boxing                              no boxing

这是因为接口类型被视为引用类型;请记住,您可以null 分配给IFooBar 类型的变量,但不能分配给Foo 类型的变量!

旁注:如果实现类型是struct,或许也可以查看this question

虚拟调度

但是,实现接口方法的方法在内部的处理方式与虚拟方法类似;即,即使您没有声明实现方法virtual,它们也会像虚拟方法一样在调度表中获得一个槽。

不要太担心这个。虚拟方法分派不应该被视为面向对象语言中的问题——这很正常。您不太可能看到由它引起的任何性能问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 2014-02-07
    • 2013-12-03
    • 1970-01-01
    • 2018-03-14
    • 2014-06-11
    • 2014-03-19
    相关资源
    最近更新 更多