c# 9.0新特性——模塊初始化器
作者:MarkKang
出處:https://www.cnblogs.com/markkang/
1 背景動(dòng)機(jī)
關(guān)于模塊或者程序集初始化工作一直是C#的一個(gè)痛點(diǎn),微軟內(nèi)部外部都有大量的報(bào)告反應(yīng)很多客戶一直被這個(gè)問(wèn)題困擾,這還不算沒(méi)有統(tǒng)計(jì)上的客戶。那么解決這個(gè)問(wèn)題,還有基于什么樣的考慮呢?
- 在庫(kù)加載的時(shí)候,能以最小的開(kāi)銷(xiāo)、無(wú)需用戶顯式調(diào)用任何接口,使客戶做一些期望的和一次性的初始化。
- 當(dāng)前靜態(tài)構(gòu)造函數(shù)方法的一個(gè)最大的問(wèn)題是運(yùn)行時(shí)會(huì)對(duì)帶有靜態(tài)構(gòu)造函數(shù)的類(lèi)型做一些額外的檢查。這是因?yàn)橐獩Q定靜態(tài)構(gòu)造函數(shù)是否需要被運(yùn)行所必須的一步,但是這個(gè)又有著顯著的開(kāi)銷(xiāo)影響。
- 使源代碼生成器在不需要用戶顯式調(diào)用一些東西的情況下能運(yùn)行一些全局的初始化邏輯。
2 詳細(xì)設(shè)計(jì)
C# 9.0將模塊初始化器設(shè)計(jì)為一個(gè)Attribute,用這個(gè)Attribute來(lái)修飾進(jìn)行模塊初始化邏輯的方法,就實(shí)現(xiàn)了模塊初始化功能。這個(gè)Attribute被命名為ModuleInitializerAttribute,具體定義如下:
using System;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
如果要使用模塊初始化器,你只要將ModuleInitializerAttribute用在符合下面要求的方法上就可以了。
- 該方法必須使靜態(tài)的、無(wú)參的、返回值為void的函數(shù)。
- 該方法不能是泛型或者包含在泛型類(lèi)型里
- 該方法必須是可從其所在模塊里訪問(wèn)的。也就是說(shuō),方法的有效訪問(wèn)符必須是internal或者public,不能是局部方法。
using System.Runtime.CompilerServices;
class MyClass
{
[ModuleInitializer]
internal static void Initializer()
{
// ...
}
}
被修飾為ModuleInitializerAttribute的靜態(tài)方法會(huì)被編譯器在編譯時(shí),在全局的靜態(tài)構(gòu)造函數(shù)中生成此代碼調(diào)用。如果有多個(gè)被修飾為初始化器的函數(shù),則每個(gè)函數(shù)生成一個(gè)初始化器代碼調(diào)用,這些初始化器代碼調(diào)用代碼會(huì)按照一定的順序(類(lèi)型名稱(chēng)順序和代碼順序)生成。當(dāng)模塊在被加載時(shí),全局靜態(tài)構(gòu)造函數(shù)開(kāi)始執(zhí)行,從而完成模塊代碼初始化工作。
3 問(wèn)題與最佳實(shí)踐
模塊初始化器與靜態(tài)構(gòu)造函數(shù)之間有著一定的關(guān)聯(lián)影響。因?yàn)槟K初始化器是一個(gè)靜態(tài)方法,因而其被調(diào)用執(zhí)行前,必然會(huì)引起其所處類(lèi)型的靜態(tài)構(gòu)造函數(shù)的執(zhí)行。請(qǐng)參考下列示例:
static class ModuleInit
{
static ModuleInit()
{
//先執(zhí)行
Console.WriteLine("ModuleInit靜態(tài)構(gòu)造函數(shù) cctor");
}
[ModuleInitializer]
internal static void Initializer()
{
//在靜態(tài)構(gòu)造函數(shù)執(zhí)行后才執(zhí)行
Console.WriteLine("模塊初始化器");
}
}
在一個(gè)模塊中指定多個(gè)模塊初始化器的時(shí)候,他們之間的順序也是一個(gè)值得注意的問(wèn)題。以上這些問(wèn)題的存在,就要求我們注意以下幾點(diǎn):
在指定了模塊初始化器的類(lèi)型中,不要在靜態(tài)構(gòu)造函數(shù)中,寫(xiě)與模塊初始化器中代碼有著順序依賴(lài)代碼,最好的就是不要使用靜態(tài)構(gòu)造函數(shù)。
多個(gè)模塊初始化器之間的代碼,也不要有任何依賴(lài)關(guān)系,保持各個(gè)初始化器代碼的獨(dú)立性。
4 結(jié)束語(yǔ)
日常開(kāi)發(fā)中,我們通常需要在模塊初始化的時(shí)候,做一些前置性的準(zhǔn)備工作,以前常采用靜態(tài)構(gòu)造函數(shù)這種不具有全局性方法,局限性很大,現(xiàn)在,這些都得到了完美解決。
以上就是c# 9.0新特性——模塊初始化器的詳細(xì)內(nèi)容,更多關(guān)于c# 9.0新特性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- C#9.0新特性詳解——頂級(jí)程序語(yǔ)句(Top-Level Programs)
- C# 9.0新特性——擴(kuò)展方法GetEnumerator支持foreach循環(huán)
- C# 9.0新特性——只初始化設(shè)置器
- C#9.0主要特性的一些想法
- C#9.0 新特性簡(jiǎn)介
- 淺析C# 9.0 新特性之 Lambda 棄元參數(shù)
- 淺談C# 9.0 新特性之只讀屬性和記錄
- 淺談C#9.0新特性之參數(shù)非空檢查簡(jiǎn)化
- c# 9.0新特性nint和Pattern matching的使用方法
- C# 9.0 新特性之模式匹配簡(jiǎn)化的實(shí)現(xiàn)
- C# 9.0 特性全面總結(jié)
相關(guān)文章
C#實(shí)現(xiàn)鬧鐘AlarmClock實(shí)例代碼
這篇文章主要介紹了C#實(shí)現(xiàn)鬧鐘AlarmClock實(shí)例代碼,很實(shí)用的功能,需要的朋友可以參考下2014-08-08
js驗(yàn)證電話號(hào)碼手機(jī)號(hào)碼的正則表達(dá)式
本篇文章主要是對(duì)js驗(yàn)證電話號(hào)碼手機(jī)號(hào)碼的正則表達(dá)式進(jìn)行了介紹。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01

