實例化類或結構時,將會調用其構造函數。 構造函數與該類或結構具有相同名稱,并且通常初始化新對象的數據成員。
在下面的示例中,通過使用簡單構造函數定義了一個名為 Taxi 的類。 然后使用 new 運算符對該類進行實例化。 在為新對象分配內存之后,new 運算符立即調用 Taxi 構造函數。
public class Taxi
{public bool IsInitialized;public Taxi(){IsInitialized = true;}
}class TestTaxi
{static void Main(){Taxi t = new Taxi();Console.WriteLine(t.IsInitialized);}
}
不帶任何參數的構造函數稱為“無參數構造函數”。 每當使用 new 運算符實例化對象且不為 new 提供任何參數時,會調用無參數構造函數。 C# 12 引入了主構造函數。 主構造函數指定為初始化新對象而必須提供的參數。?
除非類是靜態的,否則 C# 編譯器將為無構造函數的類提供一個公共的無參數構造函數,以便該類可以實例化。?
通過將構造函數設置為私有構造函數,可以阻止類被實例化,如下所示:
class NLog
{// Private Constructor:private NLog() { }public static double e = Math.E; //2.71828...
}
?結構類型的構造函數類似于類構造函數。 使用 new 實例化結構類型時,將調用構造函數。 將 struct 設置為其 default 值時,運行時會將結構中的所有內存初始化為 0。 在 C# 10 之前,structs 不能包含顯式無參數構造函數,因為編譯器會自動提供一個。?
以下代碼使用 Int32 的無參數構造函數,因此可確保整數已初始化:
int i = new int();
Console.WriteLine(i);// 但是,下面的代碼會導致編譯器錯誤,因為它不使用 new,而且嘗試使用尚未初始化的對象:
int i;
Console.WriteLine(i);// 或者,可將基于 structs 的對象(包括所有內置數值類型)初始化或賦值后使用,如下面的示例所示:
int a = 44; // Initialize the value type...
int b;
b = 33; // Or assign it before using it.
Console.WriteLine("{0}, {1}", a, b);
類和結構都可以定義采用參數的構造函數,包括主構造函數。 必須通過 new 語句或 base 語句調用帶參數的構造函數。 類和結構還可以定義多個構造函數,并且二者均無需定義無參數構造函數。 例如:
public class Employee
{public int Salary;public Employee() { }public Employee(int annualSalary){Salary = annualSalary;}public Employee(int weeklySalary, int numberOfWeeks){Salary = weeklySalary * numberOfWeeks;}
}
可使用下面任一語句創建此類:
Employee e1 = new Employee(30000);
Employee e2 = new Employee(500, 52);
構造函數可以使用 base 關鍵字調用基類的構造函數。 例如:
public class Manager : Employee
{public Manager(int annualSalary): base(annualSalary){//Add further instructions here.}
}
在此示例中,在執行構造函數塊之前調用基類的構造函數。 base 關鍵字可帶參數使用,也可不帶參數使用。 構造函數的任何參數都可用作 base 的參數,或用作表達式的一部分。?
在派生類中,如果不使用 base 關鍵字來顯式調用基類構造函數,則將隱式調用無參數構造函數(若有)。 下面的構造函數聲明等效:
public Manager(int initialData)
{//Add further instructions here.
}public Manager(int initialData): base()
{//Add further instructions here.
}
如果基類沒有提供無參數構造函數,派生類必須使用 base 顯式調用基類構造函數。
構造函數可以使用 this 關鍵字調用同一對象中的另一構造函數。 和 base 一樣,this 可帶參數使用也可不帶參數使用,構造函數中的任何參數都可用作 this 的參數,或者用作表達式的一部分。 例如,可以使用 this 重寫前一示例中的第二個構造函數:
public Employee(int weeklySalary, int numberOfWeeks): this(weeklySalary * numberOfWeeks)
{
}
上一示例中使用 this 關鍵字會導致此構造函數被調用:
public Employee(int annualSalary)
{Salary = annualSalary;
}
可以將構造函數標記為public、private、protected、internal、protected internal 或 private protected。 這些訪問修飾符定義類的用戶構造該類的方式。?
可使用 static 關鍵字將構造函數聲明為靜態構造函數。 在訪問任何靜態字段之前,都將自動調用靜態構造函數,它們用于初始化靜態類成員。