第九章 方法[《.net架構程式設計》讀書筆記]

來源:互聯網
上載者:User
.net架構|筆記|程式|設計 第九章 方法




一、 執行個體構造器

1、 前面提到用new操作符建立對象時的三部曲:

l 為對象分配記憶體

l 初始化對象的附加成員(方法表指標和SyncBlockIndex)

l 調用執行個體構造器初始化執行個體狀態

在分配記憶體時,系統將所有記憶體位置均置為0值,這就是為什麼欄位初始化而未賦值時均為0或null值。



不調用執行個體構造器的情況:

l 調用Object.MemberwiseClone()方法建立執行個體(分配記憶體;初始化附加成員;將來源物件位元組拷貝到新建立的對象)

l 還原序列化對象時

2、 為避免為執行個體欄位產生過多的構造器代碼,應避免在聲明欄位時為欄位符初值,而是在無參構造器中為它們符初值,在其他重載的構造器中調用無參構造器。



3、 實值型別執行個體構造器

l C#編譯器不會自動調用其構造器,必須顯式調用構造器才能起作用

l C#編譯器不允許為實值型別定義無參執行個體構造器(下面會介紹可以定義無參類型構造器)

l 不能為結構中的欄位在聲明的同時賦初值,可通過定義帶參構造器的方式進行

l 必須在結構的構造器中為所有欄位賦初值

二、 類型構造器

1、 類型構造器的一些限制:

l 不能帶任何參數

l 類型構造器總為私人的,不能用其他存取修飾詞

2、類型構造器被調用的時機:

l 第一個執行個體被建立,或者類型的第一個欄位或成員第一次被訪問之前

l 非繼承靜態欄位被第一次訪問之前

類型構造器在類型的生命週期中只被調用一次;

3、一些限制:

l 若類型構造器中拋出異常,則該類型變成不可訪問,訪問其中的任何欄位或方法均會拋出System.TypeInitializationException異常

l 類型構造器只能訪問類型的靜態欄位

l 類型構造器不應該調用基底類型的類型構造器,因靜態欄位並非繼承而是編譯時間靜態繫結

三、 操作符重載

1、 操作符重載

C#中對操作符重載的一些限制:

l 必須聲明為public static

l 必須有一個參數為操作符所屬類型

l 不能改變操作符原始定義的引數個數

l 若定義了true操作符也必須同時定義false操作符,二者都必須返回bool值

l ++、--操作符必須返回其所隸屬之類型的一個執行個體

l 可被重載的一元操作符:+、-、!、~、++、--、true、false

l 可被重載的二元操作符:+、-、*、/、%、!、^(異或)、<、>、<<、>>、==、!=、<=、>=

l 不允許被重載的操作符:&&、||、=、?:、+=、-=、/=、%=、|=、^=、<<=、>>=,實際上其中一些“複式操作符”在二元操作符被重載後自動產生,而不能顯式定義

l 必須成對重載的操作符:(== ,!=)、(<,>)、(<=,>=)

l ++、--操作符重載時不能區分其為前置或後置的

2、 操作符重載與語言互通性

編譯器會為重載的操作符產生一個特殊名稱的方法,如+(加)操作符產生op_Addition()方法,並為該方法的定義條目上加上specialname標記。當某種語言不能進行操作符重載時,可以直接定義具有該特殊名稱的方法,以在其他語言中調用;或直接調用具有該特殊名稱的方法以適應某種語言不能解析操作符的限制。如:vb中不能重載操作符,可顯式定義op_Addition()方法以在C#中調用;C#中定義的+操作符不能被VB識別,可顯式調用op_Addition()方法獲得同樣的功能。

四、 轉換操作符

轉換操作符的一些限制:

l 必須為public static

l 必須指定關鍵字implicit或explicit,原則為:從本類型轉換為其他類型使用implicit,將其他類型轉換為本類型用explicit,不能都使用implicit



五、 方法參數

1、 引用參數

l 預設情況下為值傳遞

l 標誌為out的參數,在調用方法前不必初始化,但返回之前必須賦值,沒有被初始化的參數是不能被使用

l 標誌為ref的參數,在調用方法前必須初始化,否則觸發編譯錯誤

l 可以使用ref或out來進行方法的重載,但不能通過區分ref和out來重載方法

l 按引用方式傳遞的變數(實參)必須和方法聲明的參數(形參)類型完全相同,否則觸發編譯錯誤。

2、 可變數目參數

使用params關鍵字及對象數組的方式指定可變參數序列。一些限制:

l 只有方法的最後一個參數才能使用可變數目參數



六、 虛方法

1、 虛方法的調用機理

CLR使用以下兩個IL指令調用方法:

u call 根據類型(即引用的靜態類型、宣告類型)來調用一個方法

u callvirt 根據對象(即引用的動態類型、實際類型)來調用一個方法

對於虛方法使用call來調用的情況有:

l base.虛方法(),

l 密封類型引用虛方法,因為沒有必要檢驗密封類型的實際類型

l 實值型別,避免被裝箱

使用callvirt調用非虛方法的情況:

l 應用變數為null時,使用callvirt才會拋出System.NullReferenceException異常,而call不會拋出

無論call或callvirt調用方法,均會有一個隱含的this指標作為方法的第一個參數,它指向正在操作的對象

2、 虛方法的版本控制:

用下面的例子說明:

using System;



class BaseClass

{

public void NonVirtualFunc()

{

Console.WriteLine("Non virtual func in base class");

}



public virtual void VirtualFunc()

{

Console.WriteLine("Virtual func in base class");

}

}



class DevicedClass : BaseClass

{

//若不使用new 關鍵字則編譯器會有warning:

//“DevicedClass.NonVirtualFunc()”上要求關鍵字

//new,因為它隱藏了繼承成員“BaseClass.NonVirtualFunc()”

public new void NonVirtualFunc()

{

Console.WriteLine("Non virtual func in deviced class");

}

//若不添加關鍵字override或new,則編譯器會有warning:

//“DevicedClass.VirtualFunc()”將隱藏繼承的成員“BaseClass.VirtualFunc()

//”。若要使當前成員重寫該實現,請添加關鍵字 override。否則,添加關鍵字

//new。

public override void VirtualFunc()

{

Console.WriteLine("Virtual func in deviced class");

}

}



class TestClass

{

public static void Main()

{

//衍生類別執行個體調用 非虛 及 虛函數

DevicedClass dc = new DevicedClass();

dc.NonVirtualFunc();

dc.VirtualFunc();



//基類執行個體調用 非虛 及 虛函數

BaseClass bc = new BaseClass();

bc.NonVirtualFunc();

bc.VirtualFunc();



//指向衍生類別執行個體的基類引用 調用 非虛 及 虛函數

BaseClass bc1 = dc;

bc1.NonVirtualFunc();

bc1.VirtualFunc();

}

}



/*

在虛函數上使用關鍵字override的運行結果:

Non virtual func in deviced class

Virtual func in deviced class

Non virtual func in base class

Virtual func in base class

Non virtual func in base class

Virtual func in deviced class

*/



/*

在虛函數上使用關鍵字new的運行結果

Non virtual func in deviced class

Virtual func in deviced class

Non virtual func in base class

Virtual func in base class

Non virtual func in base class

Virtual func in base class

*/

由上可見:new 和 override在衍生類別中協調版本的控制,在第七章中已經看到oeverride只能用於virtual方法,new則可用於非虛或虛方法,以實現隱藏基類中的同名方法。在虛函數上使用override,重寫了基類的方法,並無隱藏,這也就實現了多態。我們可設想這樣的結論:new使用call指令調用靜態類型的方法,而override使用callvirt指令調用動態類型的方法。

希望這個例子對您的理解有所協助。


相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。