在C#中聲明基本構造函數的語法:
public class MyClass
...{
public MyClass()
...{
....
}
}
在C#中沒有必要給類提供構造函數,一般情況下如果沒有提供任何構造函數,編譯器會在後台創建一個默認的構造函數。這是一個非常基本的構造函數,只能把所有的成員字段初始化為標准的默認值。否則就要編寫自己的構造函數。
構造函數的重載遵循與其他方法相同的規則,可以為它提供任意多的重載,只要它們的簽名有明顯區別即可:
public MyClass()
...{
...........
}
public MyClass(int number)
...{
...........
}
但要注意,如果提供了帶參數的構造函數,編譯器就不會自動提供默認的構造函數,只有在沒有定義任何構造函數時,編譯器才會提供默認的構造函數。
可以把構造函數定義為private或protected,這樣不相關的類就不能訪問它們。
public class MyNumber
...{
private int number;
private MyNumber(int number)
...{
this.number = number;
}
}
上面的例子在以下兩種情況下是有用的:
靜態構造函數
C#的一個新特征是也可以給類編寫無參數的靜態構造函數。這種構造函數只執行一次。
class MyClass
...{
static MyClass()
...{
......
}
}
編寫靜態構造函數的一個原因是類有一些靜態字段或屬性,需要在第一次使用類之前,從外部源中初始化它們。.Net運行庫沒有確保靜態構造函數什麼時候執行,所以不要把要求在某個特定時刻執行的代碼放在靜態構造函數中,也不能預計不同類的靜態構造函數按照什麼順序執行,但可以保證在代碼引用類之前至多執行一次。C#中靜態構造函數通常在第一次調用類的成員之前執行。
靜態構造函數沒有訪問修飾符,因為在加載類時總是由.Net運行庫調用它。同樣靜態構造函數也不能帶任何參數,一個類也只能有一個靜態構造函數。很顯然,靜態構造函數只能訪問類的靜態成員,不能訪問實例成員。
無參數的實例構造函數可以在類中與靜態構造函數共存,因為靜態構造函數是在加載類時執行,而實例構造函數是在創建實例時執行。
從其他構造函數中調用構造函數
有時在一個類中有幾個構造函數,以包容某些可選參數,這些構造函數都包含一些共同的代碼:
Class Car
private string description;
private uint nWheels;
public Car(string description, uint nWheels)
...{
this.description = description;
this.nWheels = nWheels;
}
public Car(string description)
...{
this.description = description;
this.nWheels = 4;
}
...........
}
兩個構造函數初始化了相同的字段,顯然可以把所有代碼放在一個地方。C#的構造函數初始化器可以實現它:
class Car
...{
private string description;
private uint nWheels;
public ;Car(string description , uint nWheels)
...{
this.description = description;
this.nWheels = nWheels;
}
public Car(string description) : this(description , 4)
...{
}
.......
}
this關鍵字僅調用參數最匹配的那個構造函數,構造函數初始化器在構造函數之前執行。
C#構造函數初始化器可以包含對同一個類的另一個構造函數的調用,也可以包含對直接基類的構造函數的調用(語法相同,但使用base關鍵字替換this),構造函數初始化器中不能有多個調用。
只讀字段
常量有時不能滿足所有要求,可能需要一些變量,其值不應改變,但在運行之前其值是未知的。C#提供了只讀字段。
readonly比const靈活得多,允許把一個字段設置為常量,但可以執行一些運算。規則是可以在構造函數中給只讀字段賦值,但不能在其他地方賦值。只讀字段還可以是一個實例字段,而不是靜態字段。不同的實例可以有不同的值。如果要把只讀字段設置為靜態就要顯式聲明。