c# 類成員初始化順序的特殊情況
這里直接給出C#類成員一般初始化順序:
- 子類靜態(tài)字段
- 子類靜態(tài)構造
- 子類實例字段
- 父類靜態(tài)字段
- 父類靜態(tài)構造
- 父類實例字段
- 父類實例構造
- 子類實例構造
為什么說是“一般”初始化順序呢?因為根據(jù)類結構的不同,類成員的初始化順序并不是一成不變的。但是這個順序是基礎,可以推導出其他特殊的初始化順序。下面我們就來看兩種特殊的情況:
static void Main(string[] args)
{
Console.WriteLine("---------------一般初始化順序---------------");
var child1 = new Child1();
Console.WriteLine("\n---------------子類靜態(tài)字段初始化需要使用父類靜態(tài)字段時初始化順序---------------");
var child2 = new Child2();
Console.WriteLine("\n---------------子類靜態(tài)構造函數(shù)中使用父類靜態(tài)字段時初始化順序---------------");
var child3 = new Child3();
Console.ReadKey();
}
public class Child1 : Base1
{
public static Display ChildStatic = new Display("Child static filed");
private Display _childFiled = new Display("Child filed");
static Child1() => Console.WriteLine("Child static ctor");
public Child1() => Console.WriteLine("Child ctor");
}
public class Child2 : Base2
{
/// <summary>
/// 子類靜態(tài)字段初始化需要使用父類靜態(tài)字段
/// </summary>
public static Display ChildStatic = new Display("Child static filed", () => BaseStatic);
private Display _childFiled = new Display("Child filed");
static Child2() => Console.WriteLine("Child static ctor");
public Child2() => Console.WriteLine("Child ctor");
}
public class Child3 : Base3
{
public static Display ChildStatic = new Display("Child static filed");
private Display _childFiled = new Display("Child filed");
/// <summary>
/// 子類靜態(tài)構造函數(shù)中使用父類靜態(tài)字段
/// </summary>
static Child3()
{
Console.WriteLine("Child static ctor");
var baseStatic = BaseStatic;
}
public Child3() => Console.WriteLine("Child ctor");
}
/// <summary>
/// 3個Base類相同,這里是為了演示靜態(tài)成員的初始化
/// </summary>
public class Base1
{
public static Display BaseStatic = new Display("Base static filed");
private Display _baseFiled = new Display("Base filed");
static Base1() => Console.WriteLine("Base static ctor");
public Base1() => Console.WriteLine("Base ctor");
}
public class Base2
{
public static Display BaseStatic = new Display("Base static filed");
private Display _baseFiled = new Display("Base filed");
static Base2() => Console.WriteLine("Base static ctor");
public Base2() => Console.WriteLine("Base ctor");
}
public class Base3
{
public static Display BaseStatic = new Display("Base static filed");
private Display _baseFiled = new Display("Base filed");
static Base3() => Console.WriteLine("Base static ctor");
public Base3() => Console.WriteLine("Base ctor");
}
public class Display
{
public Display(string msg, Func<Display> displayFunc = null)
{
Console.WriteLine(msg);
var display = displayFunc?.Invoke();
}
}

補充一下:
1. 靜態(tài)構造函數(shù)是線程安全的,會在初次訪問該類所定義的其他方法、屬性或變量之前執(zhí)行
2. 編譯器會在每個構造函數(shù)(包括靜態(tài)和實例)的開頭放入適當?shù)某绦虼a,以便把你在定義成員字段時所指定的初始值設置給這些變量,這就是字段總是在構造函數(shù)執(zhí)行前初始化的原因。
3. 無論是靜態(tài)變量還是實例變量,其取值都應該在聲明的時候得以初始化。但以下3種情況不應該編寫初始化語句
- 把字段初始化為0或null。因為系統(tǒng)在執(zhí)行開發(fā)者編寫的代碼之前,就會把內(nèi)存清零,重復執(zhí)行清零指令就顯得多余了
- 字段的初始值需要根據(jù)不同的構造函數(shù)來設定。這種情況下字段的初始化放在構造函數(shù)中就可以了,否則會導致創(chuàng)建多余的對象
- 字段的初始化過程中可能出現(xiàn)異常。這種也應該放在構造函數(shù)中進行初始化,同時要注意千萬不能讓靜態(tài)構造函數(shù)中的異常脫出,因為一個AppDomain僅能調(diào)用一次某個類的靜態(tài)構造函數(shù)
通過了解類成員的初始化順序,可以讓我們更加詳細地了解程序執(zhí)行的細節(jié),避免寫出類似“在構造函數(shù)中調(diào)用虛函數(shù)或抽象函數(shù)”的代碼。
以上就是c# 類成員初始化順序的特殊情況的詳細內(nèi)容,更多關于C# 類初始化順序的資料請關注腳本之家其它相關文章!
相關文章
C#使用RichTextBox實現(xiàn)替換文字及改變字體顏色功能示例
這篇文章主要介紹了C#使用RichTextBox實現(xiàn)替換文字及改變字體顏色功能,結合實例形式洗了C#中RichTextBox組件文字替換及改變字體顏色相關操作技巧,需要的朋友可以參考下2019-02-02

