亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#中值類型和引用類型的區別深度分析

2019-10-29 21:45:34
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C#中值類型和引用類型的區別深度分析,以通俗易懂的語言形象化的分析了C#中值類型和引用類型的區別,對于深入理解C#數據類型有著不錯的參考借鑒價值,需要的朋友可以參考下
 

本文通俗易懂的分析了C#中值類型和引用類型的區別。分享給大家供大家參考。具體分析如下:

似乎“值類型和引用類型的區別”是今年面試的流行趨勢,我已然是連續三次(目前總共也就三次)面試第一個問題就遇到這個了,這是多大的概率啊,100%,哈哈,我該買彩票去!

言歸正傳,咱還是先來探討探討這二者之間有什么區別吧。記得有一次電話面試中,我直接跟面試官說:“值類型是現金,引用類型是存折”,后來想想當時說這話雖是有點兒沖動地脫口而出,但也沒什么不妥。我這人不善于背理論的教條,喜歡把書本上那些生硬的話跟現實生活中常見的事物聯系起來理解和記憶。

直白點兒說:值類型就是現金,要用直接用;引用類型是存折,要用還得先去銀行取現。

聲明一個值類型變量,編譯器會在棧上分配一個空間,這個空間對應著該值類型變量,空間里存儲的就是該變量的值。引用類型的實例分配在堆上,新建一個引用類型實例,得到的變量值對應的是該實例的內存分配地址,這就像您的銀行賬號一樣。具體哪些類型是值類型哪些是引用類型,大家翻翻書,背一背就好了,不過我想,做過一段時間的開發,即使您背不了書上教條的定義,也不會把值類型和引用類型搞混的。接下來,還是老規矩,咱看碼說話吧。

復制代碼代碼如下:
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
  
public static class ReferenceAndValue
{
    public static void Demonstration()
    {
        Person zerocool = new Person { Name = "ZeroCool", Age = 25 };
        Person anders = new Person { Name = "Anders", Age = 47 };
 
        int age = zerocool.Age;
        zerocool.Age = 22;
 
        Person guru = anders;
        anders.Name = "Anders  Hejlsberg";
 
        Console.WriteLine("zerocool's age:/t{0}", zerocool.Age);
        Console.WriteLine("age's value:/t{0}", age);
        Console.WriteLine("anders' name:/t{0}", anders.Name);
        Console.WriteLine("guru' name:/t{0}", guru.Name);
    }
}

上面這段代碼,我們首先創建了一個Person類,包含了Name和Age兩個屬性,毋庸置疑,Person類是引用類型,Name也是,因為它是string類型的(但string是很特殊的引用類型,后面將專門有一篇文章來討論),但Age則是值類型。接下來我們來看看Demonstration方法,其中演示的就是值類型跟引用類型的區別。

 

首先,我們聲明了兩個Person類的實例對象,zerocool和anders,前面提到過,這兩個對象都被分配在堆上,而zerocool和anders本身其實只是對象所在內存區域的起始地址引用,換句話說就是指向這里的指針。我們聲明對象實例時也順便分別進行了初始化,首先我們看,zerocool對象的值類型成員,我們賦值為25(對,我今年25歲),anders(待會兒你們就知道是誰了)的Name屬性,我們賦值為“Anders”。齊活兒,接下來看我們怎么干吧。

我們聲明一個值類型變量age,直接在初始化時把zerocool的Age值賦給它,顯然,age的值就是25了。但這個時候zerocool不高興了,他想裝嫩,私自把自己的年齡改成22歲,剛夠法定結婚年齡。然后我們又聲明了一個引用類型的guy對象,初始化時就把anders賦給它,然后anders露出廬山真面目了,他的名字叫“Anders Hejlsberg”(在此向C#之父致敬)。接下來我們來分別答應出這幾個變量的值,看看有什么差別。

Result01

你可能要覺得奇怪(你要不覺得奇怪,也就不用再接著往下看了),為什么我們改了zerocool.Age的值,age沒跟著變,改了anders.Name的值,guru.Name卻跟著變了呢?這就是值類型和引用類型的區別。我們聲明age值類型變量,并將zerocool.Age賦給它,編譯器在棧上分配了一塊空間,然后把zerocool.Age的值填進去,僅此而已,二者并無任何牽連,就像復印機一樣,只是把zerocool.Age的值拷貝給age了。而引用類型不一樣,我們在聲明guy的時候把anders賦給它,前面說過,引用類型包含的是只想堆上數據區域地址的引用,其實就是把anders的引用也賦給guy了,因此這二者從此指向了同一塊內存區域,既然是指向同一塊區域,那么甭管誰動了里面的“奶酪”,另一個變現出來的結果也會跟著變,就像信用卡跟親情卡一樣,用親情卡取了錢,與之關聯的信用卡賬上也會跟著發生變化。一提到錢,估計大家伙兒印象就深了些吧,呵呵!

另外,性能上也會有區別的。既然一個是直接操作內存,另一個則多一步先解析引用地址,那么顯然很多時候值類型會減小系統性能開銷。但“很多時候”不代表“所有時候”,有些時候還得量力而為,例如需要大量進行函數參數傳遞或返回的時候,老是這樣進行字段拷貝,其實反而會降低應用程序性能。另外,如果實例會被頻繁地用于Hashtable或者ArrayList之類的集合中,這些類會對其中的值類型變量進行裝箱操作,這也會導致額外的內存分配和內存拷貝操作,從應用程序性能方面來看,其實也不劃算。

哦對了,上面提到了一個概念,裝箱。那么什么是裝箱呢?其實裝箱就是值類型到引用類型的轉化過程。將一個值類型變量裝箱成一個引用類型變量,首先會在托管堆上為新的引用類型變量分配內存空間,然后將值類型變量拷貝到托管堆上新分配的對象內存中,最后返回新分配的對象內存地址。裝箱操作是可逆的,所以還有拆箱操作。拆箱操作獲取指向對象中包含值類型部分的指針,然后由程序員手動將其對應的值拷貝給值類型變量。接下來我們來看看典型的裝箱和拆箱操作。

復制代碼代碼如下:
public static class BoxingAndUnboxing
{
    public static void Demonstration()
    {
        int ageInt = new int();
 
        // Boxing operation.
        object ageObject = ageInt;
 
        //ageObject = null;
 
        // Unboxing operation.
        ageInt = (int)ageObject;
 
        Console.WriteLine(ageInt);
    }
}

在該方法中,我們首先聲明了一個值類型變量ageInt,但并未給它賦值,接著聲明了一個典型的引用類型變量ageObject,并把ageInt賦給它,這里就進行了一次裝箱操作。編譯器現在托管堆上分配一塊內存空間(空間大小為對象中包含的值類型變量所占空間總和外加一個方法表指針和一個SyncBlockIndex),然后把ageInt拷貝到這個空間中,再返回該空間的引用地址。接下來第13行則是拆箱操作,編譯器獲取到ageObject對象中值類型變量的指針,然后將其值拷貝給值類型變量。如果你把第10行注釋掉的代碼打開(這是通俗說法,其實就是取消注釋),那么第13行就會拋出System.NullReferenceException異常,要說問什么,這又會牽扯出值類型跟引用類型另一個大的不同。看見了吧,聲明ageInt時并沒有賦值,如果關掉第10行代碼,程序不會報錯,最后打印出個0,這說明在聲明值類型變量時,如果沒有初始化賦值,編譯器會自動將其賦值為0,既然值類型沒有引用,那么它就不可能為空。引用類型不一樣,它可以為空引用,一張過期作廢的銀行卡是可以存在。而如果將一個空的對象拆箱,編譯器上哪兒去找它里面的值類型變量的指針呢?所以這也是拆箱操作需要注意的地方。

 

最后,我們在把值類型和引用類型之間其它一些明顯區別大致羅列如下,以便大家能順利通過面試第一問。

所有值類型都繼承自System.ValueType,但是ValueType沒有附加System.Object包含之外其它任何方法,不過它倒是改寫了Equals和GetHashCode兩個方法。引用類型變量的Equals比較的是二者的引用地址而不是內部的值,值類型變量的Equals方法比較的是二者的值而不是……哦對了,值類型壓根兒沒有引用地址;
值類型不能作為其它任何類型的基類型,因此不能向值類型中增加任何新的虛方法,更不該有任何抽象方法,所有的方法都是sealed的(不可重寫);
未裝箱的值類型分配在棧上而不是堆上,而棧又不是GC的地盤兒,因此GC根本不過問值類型變量的死活,一旦值類型變量的作用范圍一過,它所占的內存空間就立即被回收掉,不勞GC親自動手。
以上羅列的都是值類型和引用類型之間的主要區別,文碼并茂,相信應該給你留下比較深刻的印象,雖不夠深,但愿能起到拋磚引玉的作用。如果去面SDE職位,估計這深度就差不多了。

希望本文所述對大家的C#程序設計有所幫助。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品性视频| 日韩av影视在线| 国产精品对白刺激| 81精品国产乱码久久久久久| 国产精品jizz在线观看麻豆| 日韩欧美在线视频| 久久亚洲综合国产精品99麻豆精品福利| 亚洲欧洲国产一区| 精品视频偷偷看在线观看| 国产精品极品在线| 国产欧美中文字幕| 欧美日韩中文字幕在线| 亚洲一区二区三区四区视频| 91精品久久久久久综合乱菊| 亚洲女人被黑人巨大进入| 亚洲欧美日韩国产精品| 国产精品久久久久久久久久新婚| 欧美日韩一区二区在线| 98精品在线视频| 成人a级免费视频| 亚洲国产高潮在线观看| 日韩av观看网址| 中文字幕精品—区二区| 欧美日韩综合视频| 国产丝袜精品视频| 日韩精品免费视频| 一区二区三区回区在观看免费视频| 亚洲一区二区三区在线免费观看| 欧美黄色三级网站| 国产精品久久久久久网站| 啊v视频在线一区二区三区| 欧美成人在线影院| 97婷婷大伊香蕉精品视频| 日韩av资源在线播放| 中文字幕日韩高清| 精品国产电影一区| 7m精品福利视频导航| 精品欧美国产一区二区三区| 一区二区国产精品视频| 国产97在线|亚洲| 日韩精品视频在线观看网址| 秋霞成人午夜鲁丝一区二区三区| 亚洲视屏在线播放| 精品无人国产偷自产在线| 欧美一区二三区| 成人深夜直播免费观看| 亚洲国产成人精品久久久国产成人一区| 久久精品视频va| 日韩a**站在线观看| 91精品国产91| 精品久久久免费| 国产女人18毛片水18精品| 亚洲aⅴ男人的天堂在线观看| 国产精品免费电影| 亚洲女人天堂色在线7777| 午夜伦理精品一区| 一道本无吗dⅴd在线播放一区| 亚洲色图日韩av| 国内免费久久久久久久久久久| 91美女片黄在线观看游戏| 国产精品91久久久| 日韩欧美国产成人| 欧美在线视频导航| 91色在线观看| 色综合五月天导航| 亚洲国产中文字幕在线观看| 久久精品影视伊人网| 日韩欧美在线视频日韩欧美在线视频| 亚洲日韩欧美视频一区| 亚洲一区免费网站| 国产精品自拍偷拍视频| 国内精品久久久久影院优| 亚洲美女激情视频| 91牛牛免费视频| 久久噜噜噜精品国产亚洲综合| 国产成人综合一区二区三区| 亚洲国产日韩欧美在线99| 高潮白浆女日韩av免费看| 黄色一区二区在线观看| 正在播放欧美视频| 日韩电视剧免费观看网站| 国产丝袜一区二区| 中文字幕精品—区二区| 欧美激情亚洲激情| 国产在线播放91| 欧美日韩亚洲视频一区| 国产盗摄xxxx视频xxx69| 国产精品99蜜臀久久不卡二区| 日本精品免费一区二区三区| 在线视频亚洲欧美| 懂色aⅴ精品一区二区三区蜜月| 91影院在线免费观看视频| 91产国在线观看动作片喷水| 主播福利视频一区| 亚洲一区二区三区在线视频| 欧美在线亚洲一区| 欧美性猛交xxxxx免费看| 亚洲激情视频网站| 精品国产999| www.久久撸.com| 日韩成人性视频| 国产一区av在线| 日本最新高清不卡中文字幕| 最近更新的2019中文字幕| 国产a∨精品一区二区三区不卡| 亚洲国产精品国自产拍av秋霞| 国产亚洲一区二区精品| 国产91精品久久久久久| 欧美洲成人男女午夜视频| 国产精品777| 成人有码在线播放| 日韩激情av在线免费观看| 色悠悠久久久久| 亚洲天天在线日亚洲洲精| 久久久成人av| 久久999免费视频| 日韩经典中文字幕在线观看| 日韩一二三在线视频播| 5252色成人免费视频| 日本中文字幕久久看| 川上优av一区二区线观看| 亚洲精品美女在线| 中文一区二区视频| 国产日韩欧美91| 国内精久久久久久久久久人| 久久精品免费播放| 欧美国产乱视频| 中文字幕免费国产精品| 色综合天天狠天天透天天伊人| 一区二区三区视频免费| 国产v综合ⅴ日韩v欧美大片| 欧美精品在线观看91| 麻豆乱码国产一区二区三区| 狠狠躁夜夜躁人人爽天天天天97| 午夜精品久久久久久久久久久久久| www.日韩av.com| 日韩av色综合| 午夜精品理论片| 懂色av影视一区二区三区| 国产成人精品综合久久久| 亚洲欧美日韩国产中文| 这里只有精品丝袜| 亚洲人成电影网站色www| 亚洲丝袜av一区| 日本高清+成人网在线观看| 国产精品视频播放| 欧美理论在线观看| 中文字幕欧美国内| 欧美视频在线观看免费网址| 18久久久久久| 亚洲美女在线视频| 精品亚洲va在线va天堂资源站| 久久视频在线免费观看| 欧美高清自拍一区| 日韩av电影手机在线| 国产精品91免费在线| 九九热r在线视频精品| 亚洲人成电影网站色| 欧美在线亚洲一区| 日韩中文综合网| 久久99久国产精品黄毛片入口| 欧美丰满老妇厨房牲生活| 亚洲成人黄色在线| 成人精品视频99在线观看免费|