.NET Core CSharp 初級篇 1 4 本節內容為this、索引器、靜態、常量以及只讀 簡介 在之前的課程中,我們談論過了靜態函數和欄位的一小部分知識,本節內容中,我們將詳細的講解關於對象操作的例子,以及更加深入的解釋面向對象。 常量 常量,顧名思義,就是一直為同一個值的變數,並且值不可以 ...
.NET Core CSharp初級篇 1-4
本節內容為this、索引器、靜態、常量以及只讀
簡介
在之前的課程中,我們談論過了靜態函數和欄位的一小部分知識,本節內容中,我們將詳細的講解關於對象操作的例子,以及更加深入的解釋面向對象。
常量
常量,顧名思義,就是一直為同一個值的變數,並且值不可以被改變。在C#中,定義一個常量需要使用const關鍵字聲明。常量並不占用記憶體的空間。在C#程式編譯的時候,編譯器會把任何使用了該常量替換成這個值。
因為常量並不存儲在記憶體中,因此常量只允許使用內置的數值類型,例如:bool、char、string、enum。並且聲明的同時必須對常量進行初始化。
例如我們應用的版本號,通常在應用編譯完成之後都是以一個常量存在,也不需要對他進行操作。看下列代碼。
public const string Version="v2.1.1"
public string getString(string msg)
{
return "Copyright@2019" + msg + Version;
}
上述函數代碼在編譯時,將會變成:
public string getString(string msg)
{
return "Copyright@2019" + msg + "V2.1.1";
}
因為常量的上述特性,如果Y程式集使用了X程式集中的這個Version常量,如果X修改了該常量為“2.1.2”並重新編譯,若Y不重新編譯,Y中常量還是“2.1.1”,因為該常量會被直接固化於Y中並用常量值替換變數名。因此需要y進行重新編譯才會使用新的常量值。
靜態
靜態是一個很常用的語法,我們可以在類中構造各種靜態成員,例如靜態欄位、函數等等。再C#中定義靜態成員的方法是使用修飾符static,調用的時候只需要使用“類名.成員名”。
在之前的課程中,我順帶提過一次,靜態是一個只初始化執行一次,屬於全體共有的一個東西,也可以說是該靜態成員屬於類本體所有,而不是每一個對象所有。我們就從靜態構造函數、靜態欄位、靜態函數這三塊進行一個詳細的講解。
靜態構造函數
我們之前以及對構造函數進行過一個簡單的介紹,構造函數是在類被初始化(實例化)的時候調用,並且每創建一個對象就會調用一次構造函數。
而靜態構造函數是每一個類型執行一次,也就是這個類型的所有對象公用一個靜態構造函數。這區別與普通構造函數的一個對象執行一次。並且對於靜態構造函數而言,一個類只允許有一個靜態構造函數,並且必須無參。
靜態構造函數在你訪問一個類型的靜態成員的時候,或者實例化一個類型的時候,編譯器會自動的調用靜態構造函數。
特別的,因為該初始化的構造函數(靜態構造函數)屬於所有變數共有並且會調用,那麼假設該構造函數報錯,那麼這個類將再程式剩餘生命周期內無法再被使用。
靜態欄位
靜態欄位也是一樣,屬於一切成員公有,在任何地方你都可以不實例化類的情況下對靜態欄位操作。
對於靜態欄位的初始化,分為兩種情況:
- 假定類存在一個靜態構造函數,那麼靜態欄位在靜態構造函數被調用的一瞬間就會初始化;
- 假定不存在靜態構造函數,那麼靜態欄位將會被類型被使用之前的一瞬間初始化(最晚執行),或者更早,在運行時的某一時間(並無法確定)被初始化。
靜態欄位初始化的順序則與定義時的順序一致,例如:
class A
{
public static int X = Y;
public static int Y = 15;
}
.....
Console.WriteLine("X:{0},Y:{1}",X,Y)
上例中,X,Y的初始化順序是X先被初始化,此時Y沒有初始化,則是0,因此輸出是X:0,Y:15。
靜態函數
與之前一樣,靜態函數可以在不實例化類的情況下調用,但是註意,在靜態函數中,不允許使用任何非靜態的欄位。調用的時候直接使用類名.函數名()即可。
靜態類
如果一個類,被聲明為靜態類,那麼該類不可以被實例化,也不可以被繼承,同時不可以包含非靜態成員。非靜態類中,可以包含靜態成員。
只讀
只讀用於欄位的訪問控制,使用readonly關鍵字,通常情況下也可以使用無set訪問器的屬性進行實現。
class A
{
public string test{get;}
public readonly string _test;
}
靜態成員的生命周期
從程式開始初始化到程式結束,因此濫用靜態會導致性能問題。
this關鍵字
在C#中,this關鍵字表示操作的當前對象,在類裡面,如果你使用this關鍵字,則this指代的是你每次操作對象時的當前對象。特別的,如果你的函數形參名稱和欄位名相同,並且你需要同時操作這個兩個變數,那麼你需要使用this關鍵字去指明你的操作對象,例如:
class A
{
private string data;
public string Data{get{return data;}}
public void SetData(string data)
{
//this.data表示是當前對象的欄位data
this.data = data;
}
}
索引器
在之前的數組操作中,相信大家都發現了數組的訪問通過了一個中括弧和下標的方式進行訪問,這個東西我們稱為索引器。但是在類中的索引器可以以任何類型作為索引的key,這使得整個類的拓展性變得很好。
如何去定義一個索引器呢?這裡就需要用到我們的this關鍵字了。定義的方式有點類似我們對於屬性的定義
public class A
{
public double[] arry{get;set;}
public double this [int index]
{
get
{
return arry[index];
}
set
{
arry[index] = value;
}
}
}
通過索引器,我們可以自己定義各種不同的索引方式,而不用拘泥於下標訪問
習題
1.請問下列代碼輸出什麼?為什麼?
class A
{
public static A a = new A();
public static int X = 3();
A()
{
Console.WriteLine(X);
}
}
class Program
{
static void Main()
{
Console.WriteLine(A.X);
}
}
2.試著使用索引器,寫出一個二維數組的索引訪問,要求實現倒序訪問(即a[0]訪問最後一位)
前往Github獲取更多本節資料(PPT,實例代碼)
如果我的教程幫到了您,希望您動動小手,在GitHub給我一個star