当前位置:编程学习 > C#/ASP.NET >>

[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对象本身,这些虚方法退化成了静态调用(编译期绑定)。
绿色通道:好文要顶关注我收藏该文与我联系

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,