• [C#]struct如何支持虚方法覆盖和接口继承


      我还没有研读《CLR Via C#》之类的专著,只是心里有了疑问,然后就去个人探究,下文多为猜想。更希望了解内幕的朋友告知C#后台真相。

      我自个儿琢磨出来的结论:形如 

    1 // 原始声明
    2 struct People : IFormattable
    3 {
    4 public string ToString(string format, IFormatProvider formatProvider)
    5 {
    6 return ToString();
    7 }
    8 public override string ToString() { return Name; }
    9
    10 public string Name { get; set; }
    11 }

     的结构声明,会被转化为两个后台声明:

    1 // 实际代码中的struct People被映射成这个类型,虚方法声明和接口继承都无效了
    2 struct PeoplePOD // : IFormattable
    3 {
    4 public string ToString(string format, IFormatProvider formatProvider)
    5 {
    6 return ToString();
    7 }
    8 public /* override */ string ToString() { return Name; }
    9
    10 public string Name { get; set; }
    11 }
    12 // 这是装箱后的堆对象类型,任何试图将原始struct转化为object/ValueType/接口的转型,都会被自动装箱为这个类型的对象
    13 class PeopleBox : IFormattable
    14 {
    15 public string ToString(string format, IFormatProvider formatProvider)
    16 {
    17 return ToString();
    18 }
    19 public override string ToString() { return Name; }
    20
    21 public string Name { get; set; }
    22 }

      代码中出现的所有struct People,其实都是struct PeoplePOD,即放弃了虚函数和接口继承后的纯数据+非虚方法。没有了虚方法,对象实例中就不需要为了支持多态而去包含指向类型信息的指针,故对这个struct取sizeof得到的大小等于各个字段(不包括class字段)sizeof大小之和。

      而任何将原始struct对象进行向基类的转换,都会造成装箱,装箱类型就是PeopleBox:

    1 People orgin = new People();
    2 object _object = orgin; // object _object = new PeopleBox(orgin);
    3 ValueType _valueType = orgin; // ValueType _valueType = new PeopleBox(orgin);
    4 IFormattable _iformattable = orgin; // IFormattable _iformattable = new PeopleBox(orgin);
      所以,在struct中声明的虚函数和接口继承,只在装箱后对象上完全发挥了效果,对于struct对象本身,这些虚方法退化成了静态调用(编译期绑定)。
  • 相关阅读:
    屏蔽鼠标右键/F1帮助
    vs2010如何连接到mysql数据库
    经典的数据库设计贴吧
    js子窗口刷新父窗口
    数据库三大范式
    写给毕业生
    SQL Server权限数据库设计
    .NET
    ASP.NET MVC框架(第一部分) 【转】
    什么是SQL注入法攻击 .
  • 原文地址:https://www.cnblogs.com/cbscan/p/2092832.html
Copyright © 2020-2023  润新知