程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> [C#]struct如何支持虛方法覆蓋和接口繼承

[C#]struct如何支持虛方法覆蓋和接口繼承

編輯:C#入門知識

我還沒有研讀《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對象本身,這些虛方法退化成了靜態調用(編譯期綁定)。
綠色通道:好文要頂關注我收藏該文與我聯系

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved