成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

顛覆你對方法調用的看法!

開發 后端
如果你對實例方法,虛方法的運行機制已經了如指掌,并且,對方法和對象的內存布局也心中有數,那么本文可能會顛覆你以前對他們的認識。閱讀本文的最佳方式就是親自演練一下,如果看完之后有疑惑,那么是正常的,但是稍加思考就會想明白。

注意:如果你是一個初學者,對實例方法,虛方法的調用還不太清楚,強烈建議你不要閱讀本文,因為這里面的代碼會讓你完全崩潰掉。

如果你對實例方法,虛方法的運行機制已經了如指掌,并且,對方法和對象的內存布局也心中有數,那么本文可能會顛覆你以前對他們的認識。

閱讀本文的***方式就是親自演練一下,如果看完之后有疑惑,那么是正常的,但是稍加思考就會想明白。

 

我說,string變量可以直接引用一個object對象!

我說,派生類型的變量可以直接引用基類型的對象!

你會說,老兄,別開玩笑了,派生類型怎么可以指向一個基類型的對象呢!

 

我會讓你見證一下奇跡,并在文章的結尾再給你一個更加不可思議的例子。

 

首先,請看下面的代碼:

  1. class Program {  
  2.         static void Main(string[] args) {  
  3.             Derived d=(Derived)new Base();  
  4.             d.Print();  
  5.             Console.Read();  
  6.         }  
  7.     }  
  8.             class Base {  
  9.         public void Print() {  
  10.             Console.Write("in base");  
  11.         }  
  12.     }  
  13.  
  14.     class Derived : Base {  
  15.         public new void Print() {  
  16.             Console.WriteLine("in derived");  
  17.         }  
  18.     } 

毫無疑問,在運行時一定會拋出一個異常,因為Base對象無法轉換為Derived對象。

 

但是,現在,我就想讓d指向Base對象,并且可以調用Base中的Print方法,該怎么做呢?

 

用FiledOffset可以做到這一點,但首先需要定義一個叫做Manager的類,里面包含兩個實例字段,一個為Derived,一個為Base。如下:

  1. [StructLayout(LayoutKind.Explicit)]  
  2.     class Manager {  
  3.         [FieldOffset(0)]  
  4.         public  Base b = new Base();  
  5.  
  6.         [FieldOffset(0)]  
  7.         public Derived derived;  
  8.     } 

現在,通過為b和derived都指定了相同的偏移,所以,b和derived都指向了同一個對象,Base對象。

由于derived現在指向了Base對象,那么如果我調用d.Print方法,調用的是Base的Printf還是Derived的Print方法,還是拋出一個異常。請看如下代碼:

  1. class Program {  
  2.         static void Main(string[] args) {  
  3.             Manager m = new Manager();  
  4.             m.derived.Print();  
  5.             Console.Read();  
  6.         }  
  7.     } 

運行上面代碼,會輸出什么呢?

答案是,“In Derived”。

這很不可思議,因為derived指向的是Base對象,現在調用的確實Derived的方法。想要了解原因,請看下圖:

這里,盡管derived指向的是一個Base對象,但是,CLR發現Print是一個非虛方法,所以CLR并不關心derived變量指向什么對象,CLR根據derived變量的類型來調用Print方法,這里derived是一個 Derived類型,所以CLR會調用Derived中的Print,最終輸出In Derived。

第二個例子:

下面的這個例子也很不可思議,同樣會顛覆你傳統的觀點。

讓我們將上面的print方法改為virtual方法,最終如下:

  1. [StructLayout(LayoutKind.Explicit)]  
  2.     class Manager {  
  3.         [FieldOffset(0)]  
  4.         public  Base b = new Base();  
  5.  
  6.         [FieldOffset(0)]  
  7.         public Derived derived;  
  8.     }  
  9.  
  10.     class Base {  
  11.         public virtual void Print() {  
  12.             Console.Write("in base");  
  13.         }  
  14.     }  
  15.  
  16.     class Derived : Base {  
  17.         public override void Print() {  
  18.             Console.WriteLine("in derived");  
  19.         }  
  20.     } 

現在,運行如下測試代碼:

  1. class Program {  
  2.         static void Main(string[] args) {  
  3.             Manager m = new Manager();  
  4.             m.derived.Print();  
  5.             Console.Read();  
  6.         }  
  7.     } 

這次結果會是什么呢?強烈建議你自己思考答案。

結果是,In Base!

是不是及其不可思議!為了更清楚的理解原因,請看下圖:

 

 

 

這里,盡管derived指向的是Base對象,但是,當CLR看到derived.Print這行代碼時,由于Print是虛方法,所以CLR會查看derived所指向的Base對象。

CLR發現Base對象里的type object pointer指向一個Base type object,于是就調用Base Type object中的Print方法,所以最終會輸出InBase。

 總結:

沒有總結可不好。

本質上,子類型是不能引用父類型對象的。但是,我們可以通過FieldOffset繞過這一限制。通過子類型的變量來調用父對象的方法,這很是不可思議,但更不思議的是,當子類型的變量指向父對象時,竟然可以調用子方法!

那么上面的本質是什么呢?當CLR調用一個非虛方法時,不會關心變量具體指向的是什么,因為CLR此時是通過變量的類型來調用方法。如果方法時虛方法,那么CLR為了實現多態,需要查看這個變量指向的是什么對象,然后在通過對象的type object pointer找到對應的Type Object,然后調用Type Object中的方法。

原文鏈接:http://www.cnblogs.com/francisYoung/p/3371106.html

責任編輯:林師授 來源: 博客園
相關推薦

2018-12-14 15:51:47

Pandas數據數據結構

2023-10-13 08:52:19

遠程Bean類型

2009-09-24 08:45:26

微軟競爭對手Chrome

2011-04-29 11:14:34

投影機

2010-09-25 15:52:01

2015-05-14 12:41:45

智能

2021-09-26 15:34:21

內部結構方法區

2022-08-18 09:51:50

Python代碼循環

2019-03-10 08:30:35

物聯網IoT物聯網設備

2011-01-19 15:31:46

Kmail

2022-03-28 12:23:25

企業內部威脅監管

2010-09-30 10:44:43

2013-07-02 14:45:21

Foxmail 7.1郵件

2024-06-28 12:54:45

2013-05-24 09:43:46

2022-04-15 11:37:19

密碼網絡攻擊網絡安全

2025-05-15 01:00:00

2017-12-20 10:38:25

無人駕駛自動駕駛道路測試

2018-01-13 23:17:55

谷歌研究報告團隊建設

2020-01-02 15:15:56

華為云WeLink
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九久久国产精品 | 国产99久久精品一区二区300 | 国产精品一区一区 | av网站观看 | 伊人国产精品 | 美女视频h | 亚洲首页 | 日本精品视频在线观看 | 97国产精品视频 | 黄色大片免费播放 | 精品99久久 | 9999在线视频 | 国产精彩视频在线观看 | 国产粉嫩尤物极品99综合精品 | www国产成人免费观看视频,深夜成人网 | 亚洲欧美一区二区三区国产精品 | 一区二区播放 | 欧美黄在线观看 | 中文字幕在线免费 | 国产精品一区久久久 | 羞羞的视频免费在线观看 | 亚洲高清视频一区二区 | 91天堂网| 亚洲在线一区 | 国产一区二区三区在线 | 国产一区二区在线播放视频 | 国产在线1 | 91精品久久久久久久久久 | 国产精品久久久久9999鸭 | 精品在线一区 | 在线播放亚洲 | 久久久久久久久久一区二区 | 中文字幕一二三区 | 中文字幕 视频一区 | 国产在线高清 | 亚洲一区二区在线播放 | 国产成人一区二区 | 久久久久久久综合色一本 | 国产一区二区三区 | 天天视频一区二区三区 | 久久91精品|