您好,登錄后才能下訂單哦!
單例類與靜態(tài)類在c#中的區(qū)別是什么?相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
單例模式:屬于設(shè)計模式中創(chuàng)建類型的模式,通過單例模式的方法創(chuàng)建的類,在當(dāng)前程序中只有一個實(shí)例,當(dāng)然可以實(shí)現(xiàn)為線程安全的單例。
這里簡單復(fù)習(xí)下創(chuàng)建代碼:
使用時實(shí)例化,多線程應(yīng)用時,使用不當(dāng)會有線程安全問題。
public class SingletonA { //私有成員,使用時分配內(nèi)存 private static SingletonA _instance = null; //私有構(gòu)造,杜絕直接new類 private SingletonA() { } //獲取實(shí)例 public static SingletonA GetInstance () { if (_instance == null) { _instance = new SingletonA(); } return _instance; } }
聲明實(shí)例時實(shí)例化,多線程應(yīng)用時,使用不當(dāng)會有線程安全問題。
public class SingletonB { //私有靜態(tài)成員,聲明類實(shí)例時,分配 private static readonly SingletonB _instance = new SingletonB(); //私有構(gòu)造,杜絕直接new類 private SingletonB() { } public static SingletonB GetInstance() { return _instance; } }
推薦這個,經(jīng)典的線程安全單例實(shí)現(xiàn)
public class SingletonD { private static SingletonD _instance = null; private static readonly object _lockObject = new object(); private SingletonD() { } public static SingletonD GetInstance() { if (_instance == null) { lock (_lockObject) { if (_instance == null) _instance = new SingletonD(); } } return _instance; } }
最精簡版
public sealed class SingletonC { private SingletonC() { } public static readonly SingletonC Instance = new SingletonC(); }
//FileLogger只需要定義成一般的類即可,無需按照單例模式進(jìn)行實(shí)現(xiàn),當(dāng)然也不能是靜態(tài)類。 public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSingleton<ILogger, FileLogger>(); }
我們基于以下幾個要點(diǎn)進(jìn)行比較
是否支持依賴注入
內(nèi)存管理是怎樣的
可擴(kuò)展性
可測試性
靜態(tài)類形如:
public static class StaticExample { private static readonly object lockObj = new object(); public static void Log(string message) { //Write code here to log data. } }
特性比較 | 靜態(tài)類 | 單例類 |
---|---|---|
是否支持依賴注入 | 否,編譯時提示靜態(tài)類型不能作為類型參數(shù) | 支持 |
內(nèi)存管理是怎樣的 | 靜態(tài)類存儲在托管堆的high frequency heap,僅當(dāng)應(yīng)用程序卸載時,才釋放內(nèi)存 | 單例類的單個實(shí)例是靜態(tài)的,因此也保存在high frequency heap,當(dāng)應(yīng)用程序卸載時,才釋放內(nèi)存。但是,與只能具有靜態(tài)對象的靜態(tài)類不同,單例類可以同時具有靜態(tài)和非靜態(tài)對象。因此,從內(nèi)存管理的角度來看,當(dāng)您使用單例類時,可以利用垃圾回收管理對象。 |
可擴(kuò)展性 | 您不能繼承靜態(tài)類并覆蓋其方法 ;靜態(tài)類不能具有擴(kuò)展方法 | 單例類通常包含一個私有構(gòu)造函數(shù),并標(biāo)記為已密封,以指示它既不能實(shí)例化也不能繼承;因此,只有在單例類中具有非私有構(gòu)造函數(shù)的情況下,才可以擴(kuò)展單例類;單例類可以具有擴(kuò)展方法 |
可測試性 | 模擬靜態(tài)類非常困難,特別是在包含靜態(tài)對象的時候。當(dāng)然如果是只有靜態(tài)方法,且冪等則還是很容易測試的 | 測試單例類很容易 |
看完上述內(nèi)容,你們掌握單例類與靜態(tài)類在c#中的區(qū)別是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。