c#怎樣實(shí)現(xiàn)單例模式-創(chuàng)新互聯(lián)

小編給大家分享一下c#怎樣實(shí)現(xiàn)單例模式,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

專(zhuān)業(yè)領(lǐng)域包括成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、成都做商城網(wǎng)站、微信營(yíng)銷(xiāo)、系統(tǒng)平臺(tái)開(kāi)發(fā), 與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開(kāi)發(fā)公司不同,創(chuàng)新互聯(lián)的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營(yíng)銷(xiāo)的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶(hù)提供全網(wǎng)互聯(lián)網(wǎng)整合方案。

記一下學(xué)習(xí)單例模式的筆記:

單例就是要保證該類(lèi)僅有一個(gè)實(shí)例。實(shí)現(xiàn)完全封閉的單例(外部不能new)其實(shí)就要兩點(diǎn)要求:

  • 全局訪(fǎng)問(wèn):需要一個(gè)該類(lèi)型的全局靜態(tài)變量,每次獲取實(shí)例時(shí)都要判斷它是否null,不存在new,存在通過(guò)一個(gè)方法直接返回該值獲取實(shí)例來(lái)保證對(duì)象;

  • 實(shí)例化控制:new實(shí)例不能外部new、造成實(shí)例不,需要一個(gè)私有構(gòu)造器禁用共有構(gòu)造器。


根據(jù)new實(shí)例的時(shí)機(jī),分為餓漢式和懶漢式:

一、 餓漢式單例:靜態(tài)變量初始化時(shí)new

特點(diǎn):加載時(shí)new,一開(kāi)始全局就存在該實(shí)例,每次用到只要獲取就行,提前占用系統(tǒng)資源但不存在線(xiàn)程安全問(wèn)題。代碼如下:

public sealed class Singleton
  {
    private static readonly Singleton instance = new Singleton();
    private Singleton() { }

    public static Singleton GetInstance()
    {
      return instance;
    }
  }

二、 懶漢式單例:需要該實(shí)例的時(shí)候再new

特點(diǎn):真正需要用到的時(shí)候才實(shí)例化,不提前占用資源但多個(gè)線(xiàn)程同時(shí)用到該實(shí)例時(shí),會(huì)存在判斷靜態(tài)變量都為null都去new而產(chǎn)生多個(gè)實(shí)例的情況。有線(xiàn)程安全問(wèn)題,但可以用雙重鎖定解決。

單線(xiàn)程懶漢單例代碼如下:

public class Singleton
  {
    private static Singleton instance = null;
    private Singleton() { }

    public static Singleton GetInstance()
    {
      if (instance == null)
        instance = new Singleton();
      return instance;
    }
  }

多線(xiàn)程懶漢單例代碼如下:

public class Singleton
  {
    private static Singleton instance = null;
    private static readonly object obj = new object();
    private Singleton() { }

    public static Singleton GetInstance()
    {
      //雙重鎖定
      if (instance == null)//只有為null需要實(shí)例化處理時(shí)才進(jìn)行加鎖,提高性能避免不必要的等待
      {
        lock (obj)
        {
          if (instance == null)//避免其他線(xiàn)程等待鎖釋放期間有線(xiàn)程已經(jīng)實(shí)例化,從而造成多個(gè)實(shí)例
            instance = new Singleton();
        }
      }
      return instance;
    }
  }

三、 注冊(cè)式單例

介紹一個(gè)有意思的單例-泛型注冊(cè)式,是對(duì)單例的擴(kuò)展,主要了解它的設(shè)計(jì)思想。

其實(shí)每個(gè)類(lèi)單例模式實(shí)現(xiàn)代碼都是差不多的:

  1. 相同結(jié)構(gòu)和成員(字段、屬性、行為等):是否可以考慮進(jìn)行抽象提取一個(gè)公共的調(diào)用接口?

  2. 成員類(lèi)型或輸入輸出具體類(lèi)型不是固定的:是否可以考慮設(shè)計(jì)一個(gè)適用于不同類(lèi)型的通用處理方式而不都是Object?這個(gè)適用不同類(lèi)型通用解決就要用到泛型。

實(shí)現(xiàn)代碼如下(例子使用餓漢式,當(dāng)然也可以用懶漢式):

public abstract class Singleton<T> where T:class,new()
  {
    private static readonly T instance = new T();
    protected Singleton() { }

    public static T GetSingleton()//獲取單例
    {
      return instance;
    }
  }
  public class Person : Singleton<Person> { }

可以看到這種單例通過(guò)繼承的方式,既可以new實(shí)例也可以獲取單例實(shí)例。如果要實(shí)現(xiàn)上面的完全封閉(禁用外部new),也可以完全在Person類(lèi)中寫(xiě)個(gè)私有構(gòu)造器在Singleton<T>類(lèi)中實(shí)例的獲取new T()改為反射調(diào)用私有構(gòu)造器的方式實(shí)現(xiàn),總感覺(jué)怪怪的。

下面是主程序調(diào)用該單例方法:

static void Main(string[] args)
    {
      Person p1 = Person.GetSingleton();
      Person p2 = Singleton<Person>.GetSingleton();

      if (object.ReferenceEquals(p1, p2))
      {
        Console.WriteLine("兩個(gè)對(duì)象是同一實(shí)例");
      }
      Console.ReadKey();
    }

輸出結(jié)果:

c#怎樣實(shí)現(xiàn)單例模式

看完了這篇文章,相信你對(duì)“c#怎樣實(shí)現(xiàn)單例模式”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)站標(biāo)題:c#怎樣實(shí)現(xiàn)單例模式-創(chuàng)新互聯(lián)
本文來(lái)源:http://muchs.cn/article46/dpsshg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開(kāi)發(fā)、網(wǎng)站策劃、網(wǎng)站收錄、建站公司、App設(shè)計(jì)、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)