日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

单例模式以及在C#中的使用

發布時間:2023/12/18 C# 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单例模式以及在C#中的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面做一些簡要的說明。

1.

單例模式(Singleton Pattern),又稱作單件模式,當然也有一種詼諧的稱謂:單身模式。在經典的GoF所著的《Design Patterns》一書中,對單例模式有著詳盡的介紹,這本書網上有全文版本。

?

2.

單例模式的意圖是保證一個類僅有一個實例,并且要提供一個全局訪問點來訪問這個實例。通常這個全局訪問點是一個靜態方法或者C#中的一個屬性。

?

3.

在C#中,典型的單例模式實現方法可以如下:

public class Manager { ????private static Manager Mgr; ????//constructor must be private ????private Manager() { } ????//public and static, or you can change it to Property instead of Method. ????public static Manager GetInstance() ????{ ????????if (Mgr ==?null) ????????{ ????????????Mgr =?new Manager(); ????????} ????????return Mgr; ????} }

當外部需要Manager的實例時,可以調用GetInstance()這個靜態方法。由于Manager類的構造器是私有的,這也就避免了其他方式實例化這個Manager類。GetInstance()方法內部的實現,保證了全局中只有一個Manager實例。

?

4.

問題肯定不會這么簡單就被解決,比如在多線程環境中,上述代碼就會有很大的隱患。

  • 有一種情況很常見:兩個線程同時調用GetInstance()方法;
  • 當某一個線程由于Mgr為null而進入條件判斷代碼塊的時候,而恰恰還沒有執行實例化一個Manager對象,這時候另一個線程由于Mgr為null,所以也會進入這個條件語句中

上面兩種情況,很顯然都會創建Manager實例,這也就違背了單例模式的意圖了。

利用C#的特性,我們可以把一個線程先鎖住(lock),等到這個線程完成后,再讓下一個線程訪問GetInstance()方法:

private static readonly object syncObject =?new object(); //public and static, or you can change it to Property instead of Method. public static Manager GetInstance() { ????//double check ????if (Mgr ==?null) ????{ ????????lock (syncObject) ????????{ ????????????if (Mgr ==?null) ????????????{ ????????????????Mgr =?new Manager(); ????????????} ????????} ????} ????return Mgr; }

代碼中用到了雙重檢查鎖定(double check locking)的技術,是為了提高性能考慮,因為C#中lock語句是很耗性能的。第一道檢查,是基于如果Mgr不為null的時候就不需要lock了,提高性能。第二道檢查,是基于兩個線程同時通過第一道檢查后,第一個線程解鎖后,由于Mgr此時已經不為null,所以第二個線程就不用實例化Manager了。

?

5.

單例模式有兩種實現方式,主要基于構建的方式不同:

  • 延遲初始化(Lazy Initialization),也叫“懶漢模式”:單例實例在第一次使用時被構建;
  • 熱初始化(Eager Initialization),也叫“惡漢模式”:單例實例在類加載時創建
  • 前面創建單例模式的方式都屬于延遲初始化。.NET 4.0以后提供了一個Lazy<T>泛型類,可以被應用于這個場景,省卻代碼的編寫量。

    public class Manager { ????private static Lazy<Manager> mgr =?new Lazy<Manager>(); ????? ????//version of Thread Safe ????//private static Lazy<Manager> mgr = new Lazy<Manager>(true); ????? ????private Manager() { } ????public static Manager GetInstance() ????{ ????????return mgr.Value; ????} }

    Lazy<T>的構造器重載版本可以幫我們解決多線程的問題。

    C#使用靜態初始化來完成單例模式中的熱初始化。需要注意的是,不需要考慮多線程的問題,因為CLR會自動解決多線程同步的問題。如果程序經常要用到這個實例,運用熱初始化可以顯著提高性能。

    public class Manager { ????private static readonly Manager mgr =?new Manager(); ????private Manager() { } ????public static Manager GetInstance() ????{ ????????return mgr; ????} }

    ?

    6.

    StackOverflow中對于單例模式都是持否定態度的,比如這個:

    In theory: when you need to restrict the instantiation of an object to one instance. In practice: never.

    主要基于下面幾個原因:

    • 違反了單一職責原則
    • 耦合度過大
    • 單元測試基本無法進行
    • 開發混淆,造成混亂。比如作為API提供的時候。

    總之,

    There‘s at most a can use but there no need.

    文章來源:http://laobian.me/2013/02/singleton-pattern-with-csharp.html

    轉載于:https://www.cnblogs.com/luohengstudy/p/3141968.html

    總結

    以上是生活随笔為你收集整理的单例模式以及在C#中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。