C#複習筆記(2)--C#1所搭建的核心基礎

來源:互聯網
上載者:User

標籤:參考型別   sha   安全   做了   靜態類   blog   hello   back   集合   

通過對C#1所搭建的核心基礎的深入瞭解,可以知道之後的C#版本在C#1的基礎上做了很多擴充,而這些擴充都是基於C#搭建的核心基礎而來的。

委託一、編寫委託的過程

委託經常和C語言的“函數指標”掛鈎。委託是方法參數化、函數式語言一個重要的表達方式。C#1中編寫一個委託要經過四部:

1、聲明委託類型

 delegate void StringProcessor(string param1);

 這個委託指定了一種無傳回值,有一個string類型的參數的方法。

 這個委託繼承自System.MulticastDelegate,後者又派生自System.Delegate.

 委託本身是參考型別,所以聲明委託的時候不能在方法中聲明。可以作為內部類,也可以聲明到namaspace下面。

  2.、必須有一個方法包含了要執行的代碼,這個方法要和委託聲明的簽名一致,包括參數和傳回值

  C#一中要為委託找到一個方法的話必須要和委託的簽名完全一直,在C#2中允許委託的斜邊和逆變。必須下面的委託:

delegate object SayHello(string word);  

  這個委託可以被下面這個方法執行個體化:

 static string Sayhello(object word)        {            Console.WriteLine(word);            return word.ToString();        }
3、建立委託本身


可以採用new操作符來建立一個委託的執行個體:

 SayHello say = new SayHello(Sayhello);

C#2中支援委託-方法組的轉換,所以,可以直接使用

SayHello say = Sayhello;
4、調用委託

一切準備就緒後就可以用invoke方法來完成調用。C#還可以更簡單的完成這個操作,使用

SayHello say = Sayhello;            say("hello,you");

就可以完成,不過在背後編譯器幫你完成了一些工作:

 

 二、合并和刪除委託


委託和string的特徵有一些相似:都是不易變的。這體現在委託的合并和刪除上面:

委託內部有一個巨集指令清單(invocation list):System.Delegate的靜態方法Combine和Remove負責建立新的委託執行個體。其中,Combine將兩個委託的巨集指令清單連結到一起,Remove負責將一個委託執行個體的一個操作刪除。它們都不改變原有的類型(所以說和string很像)他們都是返回一個Delegate。

很少在代碼中直接調用Delegate.Combine,Delegate.Remove而是用+=和-=操作符。這同樣是編譯器的功勞:

如果調用列表中拋出異常,那麼拋出異常的那個方法導致調用列表不在執行。

如果有傳回值,那麼調用列表會返回最後調用的那個方法的值。所以一般不會在調用列表中執行有傳回值的方法。

但是如果有必要,可以通過調用invocationlist來逐個執行方法並擷取傳回值。

三、事件

 首先來看事件的聲明:

public event SayHello SayHelloEvent;

事件是對委託的封裝,有點兒類似於屬性和後備欄位的關係,上面這句聲明編譯器會做如下工作:

1、在相同的範圍中聲明一個SayHello委託類型的私人欄位

2、聲明一個類似於屬性的塊結構,這個塊結構包含一個類似於屬性的取值方法和賦值方法,由編譯器進行命名,首碼分別是"add"和"remove"。

3、在外部,會通過+=和-=來操作事件,聲明事件時的存取修飾詞會限制這一操作。就是說如果聲明為一個private的事件的話外部是不能操作事件的。

4、在內部,+=操作符會調用“add”首碼的方法,“add”首碼的方法會調用Delegate.Combine來合併作業,同理,-=操作符會調用“remove”首碼的方法,該方法會調用Delegate.Remove來刪除操作。

5、從上面可以看出,事件就是一對兒“add"和”remove“方法。他封裝了委託,從而避免調用方直接操作委託,而是通過事件來間接的操作委託,在類的內部可以看到委託,在類外部可以看見事件。

總結一下,事件不是委託執行個體,只是成對兒出現的add/remove方法。類似與屬性的get/set方法。

類型系統的特徵

在C#4之前,C#的類型系統是靜態、顯式的和安全的。

一、靜態類型和動態類型

C#是靜態類型的:每個變數或運算式的類型在編譯時間都是已知的。只有類型已知的操作才是被允許的。靜態這個詞用來表示使用不變的類型資料來分析哪些操作可用。

與靜態類型想對應的是動態類型,動態類型的實質是變數中含有值,但那些值不限於特定的類型。所以編譯器不能執行相同形式的檢查。

二、顯示類型和隱式類型

這個討論只有在靜態語言的環境中才是成立的。對於顯式類型來說,每個變數都在聲明時指定類型。隱式類型則允許編譯器變數的用途來確定變數的類型。無論是顯式還是隱式,運算式的類型都會在編譯時間就確定。

三、型別安全與類型不安全

C#是型別安全的,C#支援一些型別安全的轉換:繼承上的、數值上的,如果使用強制類型轉換,編譯器會檢測轉換的結果,也會拋出異常來組織程式的繼續運行,C#還支援有限的協變和逆變(C#4)。但是和真正的協變和逆變還有很長一段距離。

可以通過顯式實現介面來處理協變和逆變上的一些限制。

總結一下:

C# 1是靜態類型的—— 編譯器知道你能使用哪些成員;

C# 1是顯式的—— 必須告訴編譯器變數具有什麼類型;

C# 1是安全的——除非存在真實的轉換關係, 否則不能將一種類型當做另一種類型;

靜態類型仍然不允許一個集合成為強型別的“ 字串列表” 或者“ 整數列表”, 除非針對不同的元素使用大量的重複代碼;

方法覆蓋和介面實現不允許協變性/ 逆變性。

實值型別和參考型別一、實值型別和參考型別的基礎知識

    對於參考型別的運算式(如一個變數),它的值是一個引用,而非對象。
    引用就像URL——是允許你訪問真實資訊的一小片資料。

     對於實值型別的運算式,它的值是實際的資料。

    有時,實值型別比參考型別更有效, 有時恰好相反。
    參考型別的對象總是在堆 上, 實值型別的值既可能在棧 上, 也可能在堆上,具體取決於上下文。 
    參考型別作為方法參數使用時, 參數預設是以“值傳遞”方式來傳遞的—— 但值本身是一個引用。 

    實值型別和參考型別的本質區別在於複製的方式不同:實值型別複製值本身,參考型別複製的是引用。

    兩種類型的另一個差異在於, 實值型別不可以派生出其他類型。 這將導致的一個結果就是,值不需要額外的資訊來描述值實際是什麼類型。 把它同參考型別比較, 對於參考型別來說, 每個對象的開頭都包含一個資料區塊, 它標識了對象的實際類型, 同時還提供了其他 一些資訊。 永遠都不能改變對象的類型——執行簡單的強制類型轉換時, 運行時會擷取一個引用, 檢查它引用的對象是不是目標類型的一個有效對象。如果有效, 就返回原始引用; 否則拋出異常。 引用本身並不知道對象的類型—— 所以同一個引用“ 值” 可用於( 引用) 不同類型的多個變數。 例如 下面 的 代碼:

 Stream stream=new MemoryStream();            MemoryStream memory = (MemoryStream) stream;
//第1行建立一個新的MemoryStream對象, 並將stream變數的值設為對那個新對象的引用。 第2行檢查stream的值引用的是不是一個MemoryStream( 或衍生類別型)對象,並將MemoryStream的值設定成相同的值。

    實值型別變數本身儲存的是值,參考型別變數本身儲存的是引用,這個引用裡麵包含一個指向真正對象的地址。變數的值在它聲明時的位置儲存。局部變數的值總是儲存在棧( stack)中(這個結論只有 在C#1中完全成立。以後會講到,在更高版本C#中,在特定情況下,局部變數最終可能儲存在堆中。)執行個體變數的值總是儲存在執行個體本身儲存的地方。 參考型別執行個體(對象)總是儲存在堆( heap)中, 靜態變數也是。

    按值傳遞和按引用傳遞的區別是按值傳遞的是副本,按引用傳遞的是別名。

    裝箱的背景在於實值型別和參考型別的值不同:實值型別的值就是值本身,而參考型別的值只是一個引用。

    實值型別的值會在需要參考型別的行為時被裝箱; 拆箱則是相反的過程。

 構建於C#1之上的新特性一、與委託有關的新特性

C#1中的委託-->C#2的泛型、方法群組轉換、匿名方法、委託協變性和逆變性-->C#3的lambda運算式、內建的Func、Action、泛型的介面和委託的協變性和逆變性

二、與類型系統有關的特性

C#2-->泛型、委託的協變性和逆變性-->C#3匿名型別、隱式類型、擴充方法-->C#4受限的泛型協變性和逆變性、動態類型

三、與實值型別有關的特性

C#2-->泛型、Nullable<t>可空實值型別

 

C#複習筆記(2)--C#1所搭建的核心基礎

相關文章

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.