簡單知識點:c# 中的單例類和靜態類的區別及使用場景

哈哈,我來了,我又來了,在這年關將至的時候,趁有時間,就多學習和溫習點老的知識。咱們在.net core開發中,會常常使用注入來注入一個單例類,而在沒有注入的時候,大部分狀況會本身實現一個單例類,或者更簡單的就是實現一個靜態類。而經常在使用中,都能完成特定的目的,然而它們間的區別是什麼呢?編程

1.設計模式:單例模式

單例模式:屬於設計模式中建立類型的模式,經過單例模式的方法建立的類,在當前程序中只有一個實例,固然能夠實現爲線程安全的單例。設計模式

這裏簡單複習下建立代碼:緩存

1.1 使用時分配,

使用時實例化,多線程應用時,使用不當會有線程安全問題。安全

public class SingletonA{//私有成員,使用時分配內存private static SingletonA _instance = null;//私有構造,杜絕直接new類private SingletonA() { }//獲取實例public static SingletonA GetInstance (){ if (_instance == null)
            {
                _instance = new SingletonA();
            }return _instance;
        }
    }   
複製代碼

1.2 聲明時實例化

聲明實例時實例化,多線程應用時,使用不當會有線程安全問題。多線程

 public class SingletonB{//私有靜態成員,聲明類實例時,分配private static readonly SingletonB _instance = new SingletonB();//私有構造,杜絕直接new類private SingletonB() { }public static SingletonB GetInstance(){            return _instance;
        }
    }複製代碼

1.3 雙檢鎖

推薦這個,經典的線程安全單例實現框架

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;
        }
    }複製代碼

1.4 .net 特性保證的線程安全

最精簡版ide

public sealed class SingletonC{private SingletonC() { }public static readonly SingletonC Instance = new SingletonC();
    }複製代碼

1.5 使用DI依賴注入時的實現

//FileLogger只須要定義成通常的類便可,無需按照單例模式進行實現,固然也不能是靜態類。

public void ConfigureServices(IServiceCollection services)
{
      services.AddControllersWithViews();
      services.AddSingleton<ILogger, FileLogger>();
}複製代碼

2. 單例類和靜態類的比較

咱們基於如下幾個要點進行比較函數

  • 是否支持依賴注入
  • 內存管理是怎樣的
  • 可擴展性
  • 可測試性

靜態類形如:工具

public static class StaticExample{private static readonly object lockObj = new object();public static void Log(string message){//Write code here to log data.}
    }複製代碼
特性比較 靜態類 單例類
是否支持依賴注入 否,編譯時提示靜態類型不能做爲類型參數 支持
內存管理是怎樣的 靜態類存儲在託管堆的high frequency heap,僅當應用程序卸載時,才釋放內存 單例類的單個實例是靜態的,所以也保存在high frequency heap,當應用程序卸載時,才釋放內存。可是,與只能具備靜態對象的靜態類不一樣,單例類能夠同時具備靜態和非靜態對象。所以,從內存管理的角度來看,當您使用單例類時,能夠利用垃圾回收管理對象。
可擴展性 您不能繼承靜態類並覆蓋其方法  ;靜態類不能具備擴展方法 單例類一般包含一個私有構造函數,並標記爲已密封,以指示它既不能實例化也不能繼承;所以,只有在單例類中具備非私有構造函數的狀況下,才能夠擴展單例類;單例類能夠具備擴展方法
可測試性 模擬靜態類很是困難,特別是在包含靜態對象的時候。固然若是是隻有靜態方法,且冪等則仍是很容易測試的 測試單例類很容易

3.使用場景

通過上面的對比,你應該看出端倪了。在這裏插入圖片描述性能

當您只須要一個包含多個方法的工具類時,靜態類是一個不錯的選擇,在這種狀況下您不須要實例。由於您沒有此類的任何實例,因此這個簡單的實現提升了應用程序的性能。

單例模式可用於設計只須要一個實例的類。典型示例包括用於日誌記錄,緩存,線程池等的管理器類,在這些場景,單例類是一個不錯的選擇。爲此,您應該有一個實例,以免對同一資源的請求衝突。 還有在引入了DI框架後,你應該多多使用單例類,由於實現這樣的需求,就是簡單的定義一個普通的類,而後註冊到DI中便可。

固然還有一點就是單例類更加像面向對象編程,哈哈~~~

相關文章
相關標籤/搜索