c# 類(lèi)成員初始化順序的特殊情況
這里直接給出C#類(lèi)成員一般初始化順序:
- 子類(lèi)靜態(tài)字段
- 子類(lèi)靜態(tài)構(gòu)造
- 子類(lèi)實(shí)例字段
- 父類(lèi)靜態(tài)字段
- 父類(lèi)靜態(tài)構(gòu)造
- 父類(lèi)實(shí)例字段
- 父類(lèi)實(shí)例構(gòu)造
- 子類(lèi)實(shí)例構(gòu)造
為什么說(shuō)是“一般”初始化順序呢?因?yàn)楦鶕?jù)類(lèi)結(jié)構(gòu)的不同,類(lèi)成員的初始化順序并不是一成不變的。但是這個(gè)順序是基礎(chǔ),可以推導(dǎo)出其他特殊的初始化順序。下面我們就來(lái)看兩種特殊的情況:
static void Main(string[] args)
{
Console.WriteLine("---------------一般初始化順序---------------");
var child1 = new Child1();
Console.WriteLine("\n---------------子類(lèi)靜態(tài)字段初始化需要使用父類(lèi)靜態(tài)字段時(shí)初始化順序---------------");
var child2 = new Child2();
Console.WriteLine("\n---------------子類(lèi)靜態(tài)構(gòu)造函數(shù)中使用父類(lèi)靜態(tài)字段時(shí)初始化順序---------------");
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>
/// 子類(lèi)靜態(tài)字段初始化需要使用父類(lè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>
/// 子類(lèi)靜態(tài)構(gòu)造函數(shù)中使用父類(lèi)靜態(tài)字段
/// </summary>
static Child3()
{
Console.WriteLine("Child static ctor");
var baseStatic = BaseStatic;
}
public Child3() => Console.WriteLine("Child ctor");
}
/// <summary>
/// 3個(gè)Base類(lèi)相同,這里是為了演示靜態(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();
}
}

補(bǔ)充一下:
1. 靜態(tài)構(gòu)造函數(shù)是線(xiàn)程安全的,會(huì)在初次訪(fǎng)問(wèn)該類(lèi)所定義的其他方法、屬性或變量之前執(zhí)行
2. 編譯器會(huì)在每個(gè)構(gòu)造函數(shù)(包括靜態(tài)和實(shí)例)的開(kāi)頭放入適當(dāng)?shù)某绦虼a,以便把你在定義成員字段時(shí)所指定的初始值設(shè)置給這些變量,這就是字段總是在構(gòu)造函數(shù)執(zhí)行前初始化的原因。
3. 無(wú)論是靜態(tài)變量還是實(shí)例變量,其取值都應(yīng)該在聲明的時(shí)候得以初始化。但以下3種情況不應(yīng)該編寫(xiě)初始化語(yǔ)句
- 把字段初始化為0或null。因?yàn)橄到y(tǒng)在執(zhí)行開(kāi)發(fā)者編寫(xiě)的代碼之前,就會(huì)把內(nèi)存清零,重復(fù)執(zhí)行清零指令就顯得多余了
- 字段的初始值需要根據(jù)不同的構(gòu)造函數(shù)來(lái)設(shè)定。這種情況下字段的初始化放在構(gòu)造函數(shù)中就可以了,否則會(huì)導(dǎo)致創(chuàng)建多余的對(duì)象
- 字段的初始化過(guò)程中可能出現(xiàn)異常。這種也應(yīng)該放在構(gòu)造函數(shù)中進(jìn)行初始化,同時(shí)要注意千萬(wàn)不能讓靜態(tài)構(gòu)造函數(shù)中的異常脫出,因?yàn)橐粋€(gè)AppDomain僅能調(diào)用一次某個(gè)類(lèi)的靜態(tài)構(gòu)造函數(shù)
通過(guò)了解類(lèi)成員的初始化順序,可以讓我們更加詳細(xì)地了解程序執(zhí)行的細(xì)節(jié),避免寫(xiě)出類(lèi)似“在構(gòu)造函數(shù)中調(diào)用虛函數(shù)或抽象函數(shù)”的代碼。
以上就是c# 類(lèi)成員初始化順序的特殊情況的詳細(xì)內(nèi)容,更多關(guān)于C# 類(lèi)初始化順序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#對(duì)list列表進(jìn)行隨機(jī)排序的方法
這篇文章主要介紹了C#對(duì)list列表進(jìn)行隨機(jī)排序的方法,涉及C#操作list列表的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
C#實(shí)現(xiàn)Winform無(wú)邊框移動(dòng)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)Winform無(wú)邊框移動(dòng)的方法,涉及C#針對(duì)WinForm窗口操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
C#使用RichTextBox實(shí)現(xiàn)替換文字及改變字體顏色功能示例
這篇文章主要介紹了C#使用RichTextBox實(shí)現(xiàn)替換文字及改變字體顏色功能,結(jié)合實(shí)例形式洗了C#中RichTextBox組件文字替換及改變字體顏色相關(guān)操作技巧,需要的朋友可以參考下2019-02-02
淺談c#表達(dá)式樹(shù)Expression簡(jiǎn)單類(lèi)型比較demo
下面小編就為大家?guī)?lái)一篇淺談c#表達(dá)式樹(shù)Expression簡(jiǎn)單類(lèi)型比較demo。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
C#實(shí)現(xiàn)文件與字符串互轉(zhuǎn)的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)文件與字符串互轉(zhuǎn)效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定幫助,需要的可以參考一下2022-08-08
c#之獲取本機(jī)主機(jī)名的四種方式總結(jié)
這篇文章主要介紹了c#之獲取本機(jī)主機(jī)名的四種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
C#實(shí)現(xiàn)窗體與子線(xiàn)程的交互的方法
這篇文章主要介紹了C#實(shí)現(xiàn)窗體與子線(xiàn)程的交互的方法,對(duì)初學(xué)者有一定的學(xué)習(xí)借鑒價(jià)值,需要的朋友可以參考下2014-08-08

