3、C#核心編程結構下

來源:互聯網
上載者:User

標籤:

 本學習主要參考Andrew Troelsen的C#與.NET4進階程式設計,這小節主要述說以下幾個東西:這一小節是上一小節的補充,主要涉及到一下的知識細節:1、C#方法的各種細節2、探討out、ref和params關鍵字以及選擇性參數和具名引數3、方法重載。4、C#運算元群組類型的細節和瞭解System.Array類類型中包含的功能。5、枚舉結構和結構類型。6、實值型別和參考型別的區別。7、探討可空資料類型以及?和??操作符的作用。 方法和參數修飾符和Main方法類似,自訂方法可以有或者沒有參數,也可以有或者沒有傳回值。方法可以在類或結構的範圍內實現(還可以在介面類型中設定原型)、並且可以被各種關鍵字(如internal、virtual、public等)修飾以限制其行為。方法的基本格式如下:class A{    static int Add(int x,int y){return x+y;}}接下來總結一下C#的參數修飾符。1.預設的參數傳遞行為:參數傳入函數的預設行為是按值傳遞。簡單來說,如果沒有為參數標記參數相關的修飾符,資料的副本就會被傳入函數。數值資料屬於實值型別,因此,如果在成員的範圍內改變參數的值,改變的就是調用者資料值的副本,調用者完全不會意識到這種改變。2.out修飾符:簡單來說,就是輸出參數。定義為帶有輸出參數的方法有義務在退出這個方法前,必須給參數賦一個恰當的值。如,下述方法返回x/y的和到ans中:static void Add(int x, int y, out int ans){    ans=x+y;}out參數有個很有用的用途,調用者可以通過它使用一次方法返回多個傳回值。並且,調用一個帶有輸出參數的方法也需要使用out修飾符。3.ref修飾符:說一下我的理解,ref關鍵字的用法,相當於是使得實值型別擁有類似參考型別的功能,通常是改變他們的值。下面是引用參數和輸入參數的區別:輸出參數不需要在他們被傳遞給方法之前初始化,因為方法在退出之前必須為輸出參數賦值。而引用參數必須在他們被傳遞給方法之前初始化,因為實在傳遞一個對已存在變數的引用。4.params修飾符:C#使用params關鍵字支援參數數組的使用。params關鍵字可以把可變數量的參數(相同類型)作為單個邏輯參數傳給方法。例如如下方法:static double calculate(params double[] values){}這個方法定義為一個帶有double型別參數數組,可以給它傳遞任意數量的double型別參數。例如:calculate(4.1,4.2,...)說明:為避免歧義,C#要求方法只支援一個params參數,而且必須是參數列表的最後一個參數。5.定義選擇性參數:大體上就是說,我們可以建立一個包含賦值了預設值的參數。例如下面方法:static void A(string a, string b="SB"){}其中第二個參數就是我們賦值了一個預設值的選擇性參數。同樣,為了避免歧義,選擇性參數必須放在方法簽名的最後,將選擇性參數放到非選擇性參數前面會引發編譯錯誤。6.使用具名引數調用方法:同選擇性參數一樣,支援具名引數的主要原因也是為了簡化與COM的互操作。具名引數允許我們在調用方法時以任意順序指定參數的值,因此我們可以使用冒號操作符通過名稱來指定參數而不必按位置傳遞參數。參數用法如下:例如定義一個傳遞ConsoleColor參數的B方法。void B(ConsoleColor aaa);那麼就可以這樣用這個方法:B(aaa:ConsoleColor.White);如果定義了一個包含選擇性參數的方法,具名引數就非常有用,調用該方法的時候,我們直接給具名引數賦值就行了,不用再指定選擇性參數的值了。7.成員重載:和其他的物件導向語言一樣,C#允許方法重載。簡而言之,當我們定義了一組名字相同的成員是,如果他們的參數數量(或類型)不同,這樣的成員就叫做被重載的成員。例如同樣名字的B方法,傳遞的參數一個int類型,一個是double類型,這也是允許的。B(int aa)和B(double aa)是兩個不同的方法。通過參數的類型不同來區分。 C#中的數組運算元組是一組通過數字索引來訪問的資料項目。更準確的說,數組是一組相同類型的資料點(int數組,string數組等)。數組定義類似下面:int[] myIntArray;用法如:int[] myIntArray=new int[3];賦值如:int[0]=199;1.C#數組初始化文法:除了逐字填充數組外,還可以用數組初始化文法來填充數組,通過在花括弧{}內指定每一個數組項來實現,用法如下:string[] myStrArray = new string[] { "A", "B" };2.隱式類型本地數組:var同樣可以用來定義隱式類型本地數組,定義方法如下(注意,數組的元素類型必須一樣,所以即使是隱式類型數組,內裡元素的類型也要一致,因為編譯的時候會確定類型):var myStrArray = new[] { "A", "B" };3.定義object數組:因為System.Object是.net類型系統中所有類型的最終基類,這樣的話,如果我們定義了一個object數組,它的子項就可以是任何東西。用法如下:object[] obj = new object[] { 1, "A", ‘a‘ };4.使用多維陣列:多維陣列主要有兩種,一種叫做矩形數組。一種叫做交錯數組。矩形數組排列是以矩陣的形式,聲明如下:int[,]=new int[6,6];表示聲明了一個6*6的矩形數組。交錯數組,也就是數組的數組。聲明如下:int[][] = new int[5][];聲明了一個具有五個不同數組的數組。5.數組作為參數(和傳回值)只要我們建立了一個數組,就完全可以把它當做參數進行傳遞或者作為成員傳回值接受。如下:static string[] A(){    string[] B = new string[]{"aaa"};    return B;}6.System.Array基類:我們建立的每一個數組都從System.Array類獲得很多功能。使用這些公用成員,我們就能使用統一的對項模型來運算元組。(Clear(),Sort()等)例如,反轉一個數組,操作如下:string[] A = new string[]{"A","B"};反轉用法:Array.Reverse(A); 枚舉類型在構建系統的時候,建立一組符號名來對應已知的數字值會很方便。枚舉可以協助我們實現這個功能。預設情況下,枚舉值的儲存類型是System.Int32。定義如下:enum E{sss=12,//表示從12開始aaa,//真實值13bb//真實值是14}1.控制枚舉的底層儲存:枚舉值的儲存類型也可以進行改變,如果我們將枚舉值儲存類型設定為byte而不是int,那麼可以這麼寫:enum E:byte{aaa=10,B=1,CC=100}注意,如果我們枚舉值超出了枚舉類型的範圍,那麼就會導致編譯錯誤。如上,如果讓枚舉值等於999就會引發編譯錯誤。 2.聲明枚舉變數:因為枚舉只不過是使用者自訂的類型,我們可以把它們作為函數的傳回值、方法參數、本地變數等。3.System.Enum類型:.net枚舉從該類獲得了很多功能,這個類定義了許多用來查詢和轉換某個枚舉的方法。例如Enum.GetUnderlyingType()方法,它用來返回用於儲存枚舉類型值的資料類型。4.動態擷取枚舉的成對的名稱和數值:所有的枚舉都支援ToString方法,它返回當前枚舉值的字串名。而另一個方法GetValue則可以返回枚舉的值。 結構類型同C語言中的結構一樣,結構不只是一組名稱值對,結構式可以包含許多資料欄位和操作這些欄位的成員的類型。定義結構:struct A{    public int x;    public void Disp()    {        Console.WriteLine("x={0}",x);    }}建立結構變數:第一種可以直接以結構名定義,如A a;但是這種必須為結構中的每個公用欄位賦值,否則就會出錯。另一種方法是用new關鍵字來建立結構變數,它會調用預設的建構函式,不接受任何輸入參數。A a = new A(); 實值型別和參考型別C#的結構和數組、字串以及枚舉全都派生自System.ValueType。而該來的作用是確保所有的衍生類別都分配在棧上而不是記憶體回收堆上。建立和銷毀分配再棧上的資料都很快,因為它的生命週期是由定義的範圍決定的,而分配在堆上的資料由.net拉基回收器監控,其生命週期的決定因素有很多。從功能上說,該類的唯一目的是,重寫由System.Object定義的虛方法來使用基於值的而不是基於引用的文法。由於實值型別使用基於值的文法,結構的生命週期是可以預測的,當結構變數離開定義域的範圍時,它就會立即從記憶體中移除。1.實值型別、參考型別和賦值操作符:實值型別賦值(例如結構),在棧上會保留兩個副本,給其中一個操作改變值,不會影響另一個副本的值。和棧中的實值型別相比,當對參考型別(類類型)應用賦值操作符時,我們就是在記憶體中重新導向引用變數的指向。他們相當於引用了託管堆中的同一個對象,當改變其中一個的值的時候,另一個也會改變。2.包含參考型別的實值型別:預設情況下,當實值型別包含其他參考型別時,賦值將產生一個引用的副本。這樣就有兩個獨立的結構,但每一個都包含指向記憶體中同一個對象的引用(淺複製)。如果想要執行一直‘深複製’也就是讓副本不受自己影響,即將內部引用的狀態完全複製到一個新對象中時,需要實現ICloneable介面。3.按值傳遞參考型別:大概就是將類作為參數傳遞給方法,並且在方法內部進行多次修改類的參數和重新賦值。例如:class A{    public int a;    public A(int aa)    {        a = aa;    }}方法B如下:void B(A a){    a.a = 100;//表示改變類內部的值,起作用    a=new A(99);//表示給類重新賦值,不起作用}因為, 在這裡,傳遞的值其實是複製了調用者對象的引用。由於B方法與調用者指向同一個對象,所以改變對象的狀態資料是可能的,但是無法把引用重新賦值給一個新對象。4.按引用傳遞參考型別:參考上面的例子,如果有一個C方法,它是按照引用傳遞參考型別。如:void C(ref A a){    a.a = 100;//表示改變類中a的值,起作用    a=new A(99);//表示給a執行個體分配了一個堆上新的對象,起作用}按引用傳遞參考型別時需要記住的黃金規則如下:1,如果按引用傳遞參考型別,被調用者可能改變對象的狀態資料的值和所引用的對象。2,如果按值傳遞參考型別,被調用者可能改變對象的狀態資料的值,但不能改變所引用的對象。 C#可空類型現在我們應該記得所有數值資料類型(包括Boolean資料類型)都是實值型別,按照規則,null用來建立一個空的對象引用,所以實值型別永遠不可以被賦值為null。為了定義一個可空的變數類型,應在底層資料類型中添加問號(?)作為尾碼。注意,這種文法只對實值型別是合法的。如果試圖建立一個可空的參考型別,包括字串,都是遇到編譯錯誤。同非空變數一樣,局部可空變數必須賦一個初始值。1.使用可空類型:涉及到資料庫編程時,可空資料類型可能特別有用,因為一個資料表中的列可能有意是空的。定義如下:public int? a=null;返回可空類型:public int? geta(){    return a;}2.??操作符:關於可空類型需要知道的最後一點是,可以使用??操作符。在獲得的值實際上是null時,我們可以用這個操作符給一個可空類型賦值。例如,當上述方法傳回值為null的時候,可以給本地變數賦值為100:int a = geta() ?? 100;使用??操作符的好處是,它比傳統的if/else條件的寫法更加緊湊。不過也可以使用如下代碼確保如果值為空白,則設定預設的100:int a= geta();if(!a.HasValue)    a = 100;Console.WriteLine("a的值是:{0}",a); 小結:本小結主要總結了可以用來構建自訂方法的C#關鍵字,預設情況下參數按值傳遞。然而,如果參數被標記為ref或者out,我們可以按引用進行傳遞。除此之外,我還總結了關於方法重載,以及有關數組、枚舉和結構如何在C#中定義和在.net類庫中表示的方法。最後我們俺就了實值型別和參考型別細節,以及包括當作為參數傳入方法後,他們如何反應,和如何使用?以及??操作符來和可空資料類型進行互動。

3、C#核心編程結構下

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.