日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

.net框架读书笔记---虚方法

發布時間:2025/3/15 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .net框架读书笔记---虚方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

接上一篇.net框架讀書筆記---引用參數(ref/out),

一、虛方法調用機理

  

代碼 namespace VirtualFunction
{
class Program
{
static void Main(string[] args)
{
SomeBaseClass sbc
= new SomeClass();
sbc.SomeFun();

SomeBaseClass sbcOwn
= new SomeBaseClass();
sbcOwn.SomeFun();

SomeClass sc
= new SomeClass();
sc.SomeFun();
}
}

public class SomeBaseClass
{
public virtual void SomeFun()
{
Console.WriteLine(
"Base");
}
}

public class SomeClass : SomeBaseClass
{
public override void SomeFun()
{
Console.WriteLine(
"inherited");
}
}
}

上面代碼展示了,對于虛方法的調用。

  通過檢查元數據,CLR可以確定一個非靜態方法是否為一個虛方法。然而,CLR在調用方法時并不使用該信息,CLR提供了兩個IL指令來調用方法:call和callvirt.其中call指令根據引用變量的類型(引用變量的動態類型,實際類型)來調用一個方法,而callvirt指令根據引用變量的對象類型來調用一個方法。當編譯源代碼時,編譯器知道代碼是否在調用一個虛方法,并根據此產生call和callvirt指令。

  不管最終通過call還是callvirt來調用一個實例方法,所有的實例方法都會接受一個隱藏的this 指針作為方法d哦第一個參數。其中this指針指向當前正在操作的對象。

二、虛方法的版本問題

  假設CompanyA設計一個類型Phone。

namespace CompanyA
{
class Phone
{
public void Dial()
{
Console.WriteLine(
"Phone.Dial");
}
}
}

?

  再假設CompanyB使用CompanyA的Phone作為基類又定義了一個類型BetterPhone。

代碼 namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{
public void Dial()
{
Console.WriteLine(
"BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
protected virtual void EstablishConnection()
{
Console.WriteLine(
"BetterPhone.EstablishConnection");
}

}
}

?

  當編譯以上代碼時會爆出警告“Warning?1?'CompanyB.BetterPhone.Dial()' hides inherited member 'CompanyA.Phone.Dial()'. Use the new keyword if hiding was intended.”,該警告告知開發人員BetterPhone中在定義Dial方法會隱藏Phone中的Dial方法。編譯器還告知我們通過在BetterPhone類的Dial定義前添加new關鍵字可以消除這種警告。修正后:

代碼 namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{
public new void Dial()
{
Console.WriteLine(
"BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
protected virtual void EstablishConnection()
{
Console.WriteLine(
"BetterPhone.EstablishConnection");
}

}
}

?

上面代碼警告消失。上面代碼演示了對于非虛方法的版本控制。

  虛方法的版本控制其實是一樣的,假設CompanyA也增加虛方法,看下面代碼

代碼 namespace CompanyA
{
class Phone
{
public void Dial()
{
Console.WriteLine(
"Phone.Dial");
EstablishConnection();
}

protected virtual void EstablishConnection()
{
Console.WriteLine(
"Phone.EstablishConnection");
}
}
}

  保持CompanyB的方法不要改變,編譯后仍然會出現上面的警告,解決辦法在CompanyB的虛方法前面增加new關鍵字:

代碼 namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{
public new void Dial()
{
Console.WriteLine(
"BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
protected new virtual void EstablishConnection()
{
Console.WriteLine(
"BetterPhone.EstablishConnection");
}

}
}

ps:new關鍵字告訴編譯器,子類中的方法雖然與父類方法一樣(簽名,參數),但是該方法與基類中的方法沒有任何關系。

  也有另外一種情況,CompanyB可能在得到CompanyA新版本后,認為COmpany。Phone的Dial和EstablishConnection是其期望的,那么CompanyB.BetterPhone可以完全刪除BetterPhone中的Dial方法,由于CompanyB希望告知編譯器BetterPhone中的EstablistConnnection和Phone中的EstablishConnection是相關聯的,那么new關鍵字必須要去掉,還需要將BetterPhone的virtual變為override(重寫),如下:

代碼 namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{

//刪除Dial方法,直接從基類繼承Dial

//刪除new并將virtual修改為override
//該方法將和基類的EstablishConnection建立聯系
protected override void EstablishConnection()
{
Console.WriteLine(
"BetterPhone.EstablishConnection");
}

}
}

有興趣,大家可以看看下面執行的結果是什么。

代碼 namespace VirtualFunction
{

class Program
{
static void Main(string[] args)
{
Base bsA
= new InheritedA();
bsA.Fun();
//??

Base bsB
= new InheritedB();
bsB.Fun();
//??
}
}
class Base
{
public virtual void Fun()
{
Console.WriteLine(
"BaseFun");
}
}

class InheritedA :Base
{
public new void Fun()
{
Console.WriteLine(
"InteritedFunA");
}
}

class InheritedB : Base
{
public override void Fun()
{
Console.WriteLine(
"InteritedFunB");
}
}
}

??處的輸出時什么

轉載于:https://www.cnblogs.com/sanjia/archive/2010/05/02/1726034.html

總結

以上是生活随笔為你收集整理的.net框架读书笔记---虚方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。