日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
顛覆你對(duì)方法調(diào)用的看法!

注意:如果你是一個(gè)初學(xué)者,對(duì)實(shí)例方法,虛方法的調(diào)用還不太清楚,強(qiáng)烈建議你不要閱讀本文,因?yàn)檫@里面的代碼會(huì)讓你完全崩潰掉。

創(chuàng)新互聯(lián)公司是專(zhuān)業(yè)的建甌網(wǎng)站建設(shè)公司,建甌接單;提供做網(wǎng)站、網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行建甌網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

如果你對(duì)實(shí)例方法,虛方法的運(yùn)行機(jī)制已經(jīng)了如指掌,并且,對(duì)方法和對(duì)象的內(nèi)存布局也心中有數(shù),那么本文可能會(huì)顛覆你以前對(duì)他們的認(rèn)識(shí)。

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

我說(shuō),string變量可以直接引用一個(gè)object對(duì)象!

我說(shuō),派生類(lèi)型的變量可以直接引用基類(lèi)型的對(duì)象!

你會(huì)說(shuō),老兄,別開(kāi)玩笑了,派生類(lèi)型怎么可以指向一個(gè)基類(lèi)型的對(duì)象呢!

我會(huì)讓你見(jiàn)證一下奇跡,并在文章的結(jié)尾再給你一個(gè)更加不可思議的例子。

首先,請(qǐng)看下面的代碼:

 
 
 
 
  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.     } 

毫無(wú)疑問(wèn),在運(yùn)行時(shí)一定會(huì)拋出一個(gè)異常,因?yàn)锽ase對(duì)象無(wú)法轉(zhuǎn)換為Derived對(duì)象。

但是,現(xiàn)在,我就想讓d指向Base對(duì)象,并且可以調(diào)用Base中的Print方法,該怎么做呢?

用FiledOffset可以做到這一點(diǎn),但首先需要定義一個(gè)叫做Manager的類(lèi),里面包含兩個(gè)實(shí)例字段,一個(gè)為Derived,一個(gè)為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.     } 

現(xiàn)在,通過(guò)為b和derived都指定了相同的偏移,所以,b和derived都指向了同一個(gè)對(duì)象,Base對(duì)象。

由于derived現(xiàn)在指向了Base對(duì)象,那么如果我調(diào)用d.Print方法,調(diào)用的是Base的Printf還是Derived的Print方法,還是拋出一個(gè)異常。請(qǐng)看如下代碼:

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

運(yùn)行上面代碼,會(huì)輸出什么呢?

答案是,“In Derived”。

這很不可思議,因?yàn)閐erived指向的是Base對(duì)象,現(xiàn)在調(diào)用的確實(shí)Derived的方法。想要了解原因,請(qǐng)看下圖:

這里,盡管derived指向的是一個(gè)Base對(duì)象,但是,CLR發(fā)現(xiàn)Print是一個(gè)非虛方法,所以CLR并不關(guān)心derived變量指向什么對(duì)象,CLR根據(jù)derived變量的類(lèi)型來(lái)調(diào)用Print方法,這里derived是一個(gè) Derived類(lèi)型,所以CLR會(huì)調(diào)用Derived中的Print,最終輸出In Derived。

第二個(gè)例子:

下面的這個(gè)例子也很不可思議,同樣會(huì)顛覆你傳統(tǒng)的觀點(diǎn)。

讓我們將上面的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.     } 

現(xiàn)在,運(yùn)行如下測(cè)試代碼:

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

這次結(jié)果會(huì)是什么呢?強(qiáng)烈建議你自己思考答案。

結(jié)果是,In Base!

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

 

這里,盡管derived指向的是Base對(duì)象,但是,當(dāng)CLR看到derived.Print這行代碼時(shí),由于Print是虛方法,所以CLR會(huì)查看derived所指向的Base對(duì)象。

CLR發(fā)現(xiàn)Base對(duì)象里的type object pointer指向一個(gè)Base type object,于是就調(diào)用Base Type object中的Print方法,所以最終會(huì)輸出InBase。

 總結(jié):

沒(méi)有總結(jié)可不好。

本質(zhì)上,子類(lèi)型是不能引用父類(lèi)型對(duì)象的。但是,我們可以通過(guò)FieldOffset繞過(guò)這一限制。通過(guò)子類(lèi)型的變量來(lái)調(diào)用父對(duì)象的方法,這很是不可思議,但更不思議的是,當(dāng)子類(lèi)型的變量指向父對(duì)象時(shí),竟然可以調(diào)用子方法!

那么上面的本質(zhì)是什么呢?當(dāng)CLR調(diào)用一個(gè)非虛方法時(shí),不會(huì)關(guān)心變量具體指向的是什么,因?yàn)镃LR此時(shí)是通過(guò)變量的類(lèi)型來(lái)調(diào)用方法。如果方法時(shí)虛方法,那么CLR為了實(shí)現(xiàn)多態(tài),需要查看這個(gè)變量指向的是什么對(duì)象,然后在通過(guò)對(duì)象的type object pointer找到對(duì)應(yīng)的Type Object,然后調(diào)用Type Object中的方法。


分享名稱(chēng):顛覆你對(duì)方法調(diào)用的看法!
文章分享:http://m.5511xx.com/article/dpdeehp.html