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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第十七节:易混淆的概念(静态和非静态、拆箱和装箱)

發布時間:2023/12/10 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十七节:易混淆的概念(静态和非静态、拆箱和装箱) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一. 靜態和非靜態

1. 概念介紹

  ① 靜態類(被static修飾) vs? 普通類(沒有被static修飾)

  ② 靜態成員:被static修飾的成員,比如:靜態方法、靜態字段等

  ③ 普通成員(實例成員):不被static修飾的成員,比如:普通方法、普通字段

2. 運行機制

  ① 靜態成員在程序運行的時候會“先于”實例成員被加載到內存中,靜態成員不需要單獨創建,當然靜態類也不能被實例化。

  比如:靜態字段和靜態構造函數只有在程序第一次使用該類之前被調用,而且只能調用一次,利用該特性,可以設計單例模式。

補充單例模式的代碼:

?View Code

public class STwo
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 模擬耗時的構造函數
? ? ? ? /// </summary>
? ? ? ? private STwo()
? ? ? ? {
? ? ? ? ? ? long result = 0;
? ? ? ? ? ? for (int i = 0; i < 1000000; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? result += i;
? ? ? ? ? ? }
? ? ? ? ? ? Thread.Sleep(1000);
? ? ? ? ? ? Console.WriteLine("{0}被構造...", this.GetType().Name);
? ? ? ? }

? ? ? ? private static STwo _STwo = null;
? ? ? ? /// <summary>
? ? ? ? /// 靜態的構造函數:只能有一個,且是無參數的
? ? ? ? /// 由CLR保證,只有在程序第一次使用該類之前被調用,而且只能調用一次
? ? ? ? /// </summary>
? ? ? ? static STwo()
? ? ? ? {
? ? ? ? ? ? _STwo = new STwo();
? ? ? ? }

? ? ? ? public static STwo CreateIntance()
? ? ? ? {
? ? ? ? ? ? return _STwo;
? ? ? ? }
? ? }

?View Code

public ?class SThird
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 模擬耗時的構造函數
? ? ? ? /// </summary>
? ? ? ? private SThird()
? ? ? ? {
? ? ? ? ? ? long result = 0;
? ? ? ? ? ? for (int i = 0; i < 1000000; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? result += i;
? ? ? ? ? ? }
? ? ? ? ? ? Thread.Sleep(1000);
? ? ? ? ? ? Console.WriteLine("{0}被構造...", this.GetType().Name);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 靜態變量:由CLR保證,在程序第一次使用該類之前被調用,而且只調用一次
? ? ? ? /// </summary>
? ? ? ? private static SThird _SThird = new SThird();

? ? ? ? public static SThird CreateIntance()
? ? ? ? {
? ? ? ? ? ? return _SThird;
? ? ? ? }
? ? }

  ② 實例成員:只有創建了對象(即進行了類的實例化)才會存在于內存中。

  證明:在StaticInstroduceDemo類中的靜態變量a上加斷點(方法體內部加斷點,兩次實例化類的時候加斷點),然后在客戶端實例化兩次 StaticInstroduceDemo類,分別調用ShowStaticInstroduce方法,

  發現:第一次實例化的時候進入靜態變量a上的斷點,然后在調用對應的方法,而第二次實例化的時候不再進入靜態變量a上的斷點,直接進入調用的方法。從而驗證了:靜態成員優先于實例成員進入內存,且只在第一次使用該類的時候進行初始化分配內存,后續將不在分配.

3. 基于以上運行機制可以得出以下幾個結論

① 普通類:

  a. 普通類中可以存在靜態成員(靜態方法、靜態字段),但里面的靜態方法不能調用普通類中的普通字段<普通類沒有實例化的話,普通字段是不存在的>。

  b. 普通類中普通方法可以調用里面的靜態字段<靜態成員先于實例成員加載到內存中>

eg:

② 靜態類:

靜態類中只能存在靜態成員(靜態方法和靜態字段)

4. 調用形式

  ① 靜態成員: 類名.靜態成員名

  ② 實例成員: 實例名.實例成員名

5. 聲明周期

  ① 對于C/S程序:每啟動一次,相當于一次生命周期,關閉程序生命周期結束,多次打開客戶端程序互不干擾。?

驗證:上述的ShowStaticInstroduce方法,兩次實例化后調用輸出的結果是2,3 。此時我再打開一個客戶端,結果依舊是2,3,這也很好證明了聲明周期的問題。

  ② 對于B/S程序:static修飾的成員存儲在服務器端中,與客戶端關閉與否無關。《詳見HomeController下的TestStatic方法》

驗證:打開不同瀏覽器,分別調用TestStatic1方法,發現每點擊一次按鈕,返回值增加1,關閉該瀏覽器,重新點擊,返回值在原基礎上加1.?關閉IIS重新運行,返回值重新計數。證明:在B/S模式下,static修飾的成員存儲在服務器端內存中,與客戶端關閉與否無關。

?

6. 使用場景

  ① 對于C/S程序:static修飾的變量可以當作緩存來使用。

  ② 對于B/S程序:可以利用static的特性來設計單例模式,或者面向多線程存儲數據,進行資源的共享<PS: 不考慮性能方面問題和一些極端情況>。

  ③ 作為工具類,全局資源共享。

二. 拆箱和裝箱

1. 補充兩個概念:

  值類型:int、double、char、bool、decimal、struct、enum

  引用類型:各種class類、string、數組、接口、委托、object

2. 裝箱:

  將值類型→引用類型

3. 拆箱:

  將引用類型→值類型

4. 經典面試題

請問下面代碼涉及到幾次拆箱和裝箱。

分析:

  ① 第一次裝箱發生在 object m2 = m1;

  ② 第一次拆箱發生在 (int)m2 上;

  所以很多人認為答案是:1次裝箱和1次拆箱,顯然是不對的。

    我們繼續分析,熟悉 Console.WriteLine原理的知道內部調用string.Concat()方法進行拼接,而Contact有很多重載,F12看源碼可知,

    該案例只能使用 public static String Concat(object arg0, object arg1); 這個重載,

    所以第2次裝箱和第3次裝箱發生在 m1→object 和(int)m2→object上。

  所以最終答案是 1次拆箱和3次裝箱

5.? 特別注意:用什么類型進行裝箱的,拆箱就拆成什么類型,否則會拋異常,無法進行類型轉換。

?

?

?PS:如果你對.Net其他知識感興趣,可以參考??DotNet進階系列(持續更新)??ASP.NET MVC深入淺出系列(持續更新)?ORM系列之Entity FrameWork詳解(持續更新)? ??

? ? ? ?那些年我們一起追逐的多線程(Thread、ThreadPool、委托異步調用、Task/TaskFactory、Parallerl、async和await)

總結

以上是生活随笔為你收集整理的第十七节:易混淆的概念(静态和非静态、拆箱和装箱)的全部內容,希望文章能夠幫你解決所遇到的問題。

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