C#中靜態(tài)構(gòu)造函數(shù)的幾點說明介紹
靜態(tài)構(gòu)造函數(shù)是C#的一個新特性,其實好像很少用到。不過當我們想初始化一些靜態(tài)變量的時候就需要用到它了。這個構(gòu)造函數(shù)是屬于類的,而不是屬于哪里實例的,就是說這個構(gòu)造函數(shù)只會被執(zhí)行一次。也就是在創(chuàng)建第一個實例或引用任何靜態(tài)成員之前,由.NET自動調(diào)用。
class SimpleClass
{
// Static constructor
static SimpleClass()
{
//
}
}
在使用靜態(tài)構(gòu)造函數(shù)的時候應(yīng)該注意幾點:
1、靜態(tài)構(gòu)造函數(shù)既沒有訪問修飾符,也沒有參數(shù)。因為是.NET調(diào)用的,所以像public和private等修飾符就沒有意義了。
2、是在創(chuàng)建第一個類實例或任何靜態(tài)成員被引用時,.NET將自動調(diào)用靜態(tài)構(gòu)造函數(shù)來初始化類,也就是說我們無法直接調(diào)用靜態(tài)構(gòu)造函數(shù),也就無法控制什么時候執(zhí)行靜態(tài)構(gòu)造函數(shù)了。
3、一個類只能有一個靜態(tài)構(gòu)造函數(shù)。
4、無參數(shù)的構(gòu)造函數(shù)可以與靜態(tài)構(gòu)造函數(shù)共存。盡管參數(shù)列表相同,但一個屬于類,一個屬于實例,所以不會沖突。
5、最多只運行一次。
6、靜態(tài)構(gòu)造函數(shù)不可以被繼承。
7、如果沒有寫靜態(tài)構(gòu)造函數(shù),而類中包含帶有初始值設(shè)定的靜態(tài)成員,那么編譯器會自動生成默認的靜態(tài)構(gòu)造函數(shù)。
靜態(tài)構(gòu)造函數(shù)趣談!
類的靜態(tài)構(gòu)造函數(shù)也叫類型構(gòu)造器,靜態(tài)構(gòu)造器,他調(diào)用的時刻由CLR來控制:
CLR會選擇如下時間之一來調(diào)用靜態(tài)構(gòu)造函數(shù):
1,在類型的第一個實例創(chuàng)建之前,或類型的非繼承字段或成員第一次訪問之前。這里的“之前”,代表前后銜接的意思。這里的時刻是精確的!
2,在非繼承的靜態(tài)字段或成員第一次訪問之前的某個時刻,具體時刻不定!
由于調(diào)用的時刻不確定,所以我們最好不要編寫依賴于特定的靜態(tài)構(gòu)造函數(shù)的執(zhí)行順序的代碼,這樣很容易產(chǎn)生不可預(yù)料的后果!
下面大家看看以下的Demo,我們來更加深入的看看靜態(tài)構(gòu)造函數(shù)的一些有趣的行為:
Demo1:
static void Main(string[] args)
{
Console.WriteLine(B.strText);
}
public class A
{
public static string strText;
static A()
{
strText = "aaaa";
}
}
public class B : A
{
static B()
{
strText = "bbbb";
}
}
大家猜猜結(jié)果是什么,可能有人認為輸出的是bbbb,因為訪問B.strText需要調(diào)用B類的靜態(tài)構(gòu)造函數(shù)static B()。實際上輸出的結(jié)果是aaaa,因為strText是類A的靜態(tài)字段,而類B只是繼承了這個字段,所以這里會調(diào)用類A的靜態(tài)構(gòu)造函數(shù)static A(),所以輸出結(jié)果是aaaa。這也沒有什么真正可說的,相信大家都能看出這個結(jié)果的。
下面看看第二個Demo:
Demo2:
static void Main(string[] args)
{
B b = new B();
A a = new A();
Console.WriteLine(B.strText);
}
public class A
{
public static string strText;
static A()
{
strText = "aaaa";
}
}
public class B : A
{
static B()
{
strText = "bbbb";
}
}
大家猜猜輸出結(jié)果是什么,可能有人認為會輸出aaaa,理由是new B()之前會調(diào)用static B(),然后new A()之前需要調(diào)用static A,這樣結(jié)果是aaaa,但是實際情況并非如果,正確的結(jié)果是bbbb,原因如下:
在執(zhí)行 new B(); 之前,B類的靜態(tài)構(gòu)造函數(shù)會調(diào)用,也就是會調(diào)用:
static B()
{
strText="bbbb";
}
當執(zhí)行到strText=“bbbb"的時候,這時需要訪問strText字段,而B的strText字段是從A類繼承的,所以這里需要會先調(diào)用:
static A()
{
strText="aaaa";
}
執(zhí)行這個函數(shù)以后strText的值是aaaa
然后代碼又回到static B()中,這時才執(zhí)行static B()中的strText="bbbb"這行,所以strText這時的值是bbbb
當執(zhí)行A a=new A();的時候,不會在調(diào)用A的靜態(tài)構(gòu)造函數(shù)了,因為前面已經(jīng)調(diào)用過了,靜態(tài)函數(shù)在整個應(yīng)用程序域的生命周期中只會調(diào)用一次!
請大家多指教啊!
- C#構(gòu)造函數(shù)詳解
- C# 構(gòu)造函數(shù)如何調(diào)用虛方法
- 淺談C# 構(gòu)造方法(函數(shù))
- C#類繼承中構(gòu)造函數(shù)的執(zhí)行序列示例詳解
- C#中構(gòu)造函數(shù)和析構(gòu)函數(shù)用法實例詳解
- 詳解C#編程中構(gòu)造函數(shù)的使用
- C#靜態(tài)構(gòu)造函數(shù)用法實例分析
- C#私有構(gòu)造函數(shù)使用示例
- c#只讀字段和常量的區(qū)別,以及靜態(tài)構(gòu)造函數(shù)的使用實例
- C# 靜態(tài)構(gòu)造函數(shù)使用總結(jié)
- C#構(gòu)造函數(shù)在基類和父類中的執(zhí)行順序
相關(guān)文章
運用示例簡單講解C#取消令牌CancellationTokenSource
這篇文章運用示例簡單講解C#取消令牌CancellationTokenSource,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08