這期內容當中小編將會給大家帶來有關在C#中創建單例的方法有哪些,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
第一種常見的方式創建單例:
/// <summary>
/// 不安全的單例
/// </summary>
public sealed class Singleton
{
private static Singleton _Singleton;
private Singleton() { }
public static Singleton GetSingleton()
{
if (_Singleton == null)
{
_Singleton = new Singleton();
}
return _Singleton;
}
}注:為什么說是不安全的單例,多線程訪問時可能會new多個對象...
/// <summary>
/// (多線程)安全單例
/// </summary>
public sealed class Singleton
{
private static Singleton _Singleton;
private static readonly object obj = new object();
private Singleton() { }
public static Singleton GetSingleton()
{
if (_Singleton == null)
{
//加鎖保護,在多線程下可以確保實例值被創建一次。缺點是每 次獲取單例,都要進行判斷,涉及到的鎖和解鎖比較耗資源。
lock (obj)
{
if (_Singleton == null)
{
_Singleton = new Singleton();
}
}
}
return _Singleton;
}
}注:為了解決上面第一種方式創建的不安全實例問題應用而生。
/// <summary>
/// 只讀單例
/// </summary>
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return instance;
}
}
}/// <summary>
/// 基于上面的只讀單例=自動屬性只讀單例(語法糖)
/// </summary>
public sealed class Singleton
{
private Singleton() { }
public static Singleton Instance { get; } = new Singleton();
}注:只讀屬性式=>借助readonly屬性,instance只被初始化一次,同樣達到了單例的效果。在引用函數執行第一句話之前,instance其實已經被賦值了,并不是預期的 只有到訪問Instance變量時才創建對象。
/// <summary>
/// Singleton中加上靜態構造函數。
/// </summary>
public sealed class Singleton
{
public static readonly Singleton instance = new Singleton();
private Singleton()
{
Console.WriteLine("初始化1!");
}
static Singleton()
{
}
public static Singleton Instance
{
get { return instance; }
}
}注:為了解決(第三種只讀屬性實例)在執行第一句代碼之前,實例已經被初始化問題。
/// <summary>
/// 使用Lazy創建單例,默認是線程安全的
/// </summary>
public sealed class Singleton
{
private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());//
private Singleton() { }
public static Singleton Instance
{
get
{
return instance.Value;
}
}
}// 貼一下關于上面Lazy<T> s=new Lazy<T>()參數的定義; // 摘要: // 初始化System.Lazy`1類的新實例。 懶惰初始化時 // 發生時,使用指定的初始化函數和初始化模式。 // 參數: // valueFactory: // 被調用以生成延遲初始化值的委托是必需的參數 // // isThreadSafe: // 如果要使此實例可由多個線程同時使用,則為true; false //使此實例一次只能由一個線程使用。 public Lazy(Func<T> valueFactory, bool isThreadSafe);
上述就是小編為大家分享的在C#中創建單例的方法有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。