C#深入解析数据类型
生活随笔
收集整理的這篇文章主要介紹了
C#深入解析数据类型
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
首先本文將會(huì)說(shuō)到的知識(shí)點(diǎn):
1.值類(lèi)型和引用類(lèi)型的原理
2.線程棧和托管堆
3.裝箱和拆箱
4.類(lèi)型判等
基本類(lèi)型原理:
c#的基本類(lèi)型是按照數(shù)據(jù)在計(jì)算機(jī)內(nèi)存是如何被分配來(lái)劃分,一種是值類(lèi)型(Value Type)基礎(chǔ)類(lèi)型是結(jié)構(gòu),使用中內(nèi)存保存在棧中,一種是引用類(lèi)型(Reference Type)基礎(chǔ)類(lèi)型是類(lèi),使用中內(nèi)存保存在堆中常用關(guān)鍵字new創(chuàng)造空間。還有一種特殊類(lèi)型,這里稱(chēng)之為簡(jiǎn)單類(lèi)型,string類(lèi)型是一種簡(jiǎn)單的引用類(lèi)型,它不需要new關(guān)鍵字創(chuàng)造可以直接來(lái)使用,還有一些特殊的值類(lèi)型(Simple Type)別如byte啊int等,在System.Int32結(jié)構(gòu)類(lèi)型中定義屬性和方法在Int32類(lèi)型中都可以調(diào)用,比如:int a= 1; int b = new int();。原因是因?yàn)樗械闹殿?lèi)型隱式繼承了System.ValueType,它是一個(gè)類(lèi)....上面不是說(shuō)值類(lèi)型的基礎(chǔ)類(lèi)型是個(gè)結(jié)構(gòu)嗎,在c#代碼中是看不到這種繼承關(guān)系的,這個(gè)關(guān)系只能通過(guò)MSIL代碼才可以看到,所以說(shuō)是隱式繼承的,才會(huì)有引用類(lèi)型的操作。 這里注意的是,棧(Stack)是一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),堆(Heap)是用于引用類(lèi)型分配空間的區(qū)域,創(chuàng)造一個(gè)對(duì)象將該對(duì)象的地址傳給棧上的變量 值類(lèi)型:枚舉、結(jié)構(gòu)(數(shù)值類(lèi)型、bool、用戶(hù)自定義結(jié)構(gòu)類(lèi)型) 引用類(lèi)型:關(guān)鍵字定義類(lèi)型(類(lèi)、接口、泛型、事件、委托)、內(nèi)置引用類(lèi)型(字符串、對(duì)象、動(dòng)態(tài)類(lèi)型Dynamic)那么類(lèi)型在內(nèi)存中如何表示和展現(xiàn)的呢?下面來(lái)看幾個(gè)例子 值類(lèi)型: class Program{static void Main(string[] args){int i = 1;ValueStack vals;vals.x = 2;}}public struct ValueStack{public int x;}
引用類(lèi)型: class Program{static void Main(string[] args){People pro = new People{name = "Jinx",age = 18,sex = "女"};}}public class People{public string name;public int age;public string sex;}
從上面的簡(jiǎn)單代碼和形象圖中可以得知,值類(lèi)型直接存在棧里面,而引用類(lèi)型的地址存在棧里面,值存在堆里面,簡(jiǎn)單的來(lái)說(shuō)new一個(gè)對(duì)象存在堆里面。要值得注意的是類(lèi)部類(lèi),new一個(gè)新的對(duì)象,在該對(duì)象的里面初始化類(lèi)部類(lèi),該類(lèi)部類(lèi)的對(duì)象是也是存在堆里面的,而它的引用地址的值是給到對(duì)象的變量。 知道值類(lèi)型和引用類(lèi)型在內(nèi)存分布情況后我們接著來(lái)講講大神們津津樂(lè)道的線程棧、托管堆 線程棧、托管堆: 每個(gè)正在運(yùn)行的程序都對(duì)應(yīng)著一個(gè)進(jìn)程(Process),在一個(gè)進(jìn)程內(nèi)部,可以有一個(gè)或多個(gè)線程(Thread),每個(gè)線程都擁有一塊存儲(chǔ)數(shù)據(jù)、參數(shù)、局部變量、傳進(jìn)來(lái)的數(shù)據(jù)等,這個(gè)就是線程棧。創(chuàng)建一個(gè)引用類(lèi)型的時(shí)候,引用變量也利用棧,但這時(shí)棧包含的只是對(duì)另一個(gè)內(nèi)存位置的引用地址,這個(gè)地址指向堆的一塊區(qū)域,這個(gè)區(qū)域就是托管堆(跟托管代碼不是一個(gè)概念,毫無(wú)關(guān)系)。等程序使用完或者是不再調(diào)用這個(gè)托管堆里面的數(shù)據(jù)時(shí),GC就會(huì)自動(dòng)回收空間,當(dāng)然,c#也提供了手動(dòng)回收機(jī)制,這個(gè)可以到后面講講c#的內(nèi)存回收機(jī)制。
下面來(lái)看看例子: class Program{static void Main(string[] args){int ages = 0;People pro = new People{name = "Jinx",age = 18,sex = "女"};ages = pro.age;Console.WriteLine("年齡:{0}", ages);}}public class People{public string name;public int age;public string sex;}
裝箱和拆箱:
裝箱:就是將一個(gè)值類(lèi)型轉(zhuǎn)換成等價(jià)的引用類(lèi)型。 class Program{static void Main(string[] args){int i = 4;Object boxed = i;}}MSIL代碼就不貼了,這里說(shuō)說(shuō)它的執(zhí)行過(guò)程 1)在堆上為新的對(duì)象實(shí)例分配一個(gè)內(nèi)存 2)將棧上值類(lèi)型變量的值復(fù)制到堆上的對(duì)象中 3)將堆上創(chuàng)建的對(duì)象的地址返回給引用類(lèi)型變量
拆箱:跟裝箱相反的操作,將一個(gè)已近裝箱的引用類(lèi)型轉(zhuǎn)換為值類(lèi)型。 class Program{static void Main(string[] args){int i = 4;Object boxed = i;int j = (int)boxed;}}過(guò)程: 1)獲取已裝箱對(duì)象的地址 2)將值從堆的對(duì)象中復(fù)制到棧上的值變量中。 這里要注意幾個(gè)問(wèn)題,裝箱和拆箱的操作都是在堆上進(jìn)行的,執(zhí)行速度相對(duì)來(lái)說(shuō)比較慢,所以盡量避免無(wú)意義的拆箱裝箱操作。在同種類(lèi)型中也存在這拆箱和裝箱操作,只不過(guò)是隱式的,可以省略,例如:int轉(zhuǎn)double,有些的轉(zhuǎn)換會(huì)丟失精度或者內(nèi)存溢出等情況。
類(lèi)型判等:
動(dòng)手寫(xiě)寫(xiě)幾個(gè)案例試試 class Program{static void Main(string[] args){People p1 = new People();People p2 = new People();People p3 = p1;int i = 3;double d = 3.0;Console.WriteLine("p1==p2?{0},p1==p3?{1}", p1 == p2, p1 == p3);//運(yùn)行結(jié)果:p1==p2?False,p1==p3?TrueConsole.WriteLine("p1Equals(p2)?{0},p1Equals(p3)?{1}", p1.Equals(p2), p1.Equals(p3));//運(yùn)行結(jié)果:p1Equals(p2)?False,p1Equals(p3)?TrueConsole.WriteLine("i==d?{0}", i == d);//運(yùn)行結(jié)果:i==d?TrueConsole.Read();}}從上面代碼,可以的出一些簡(jiǎn)要的結(jié)論: 1.引用類(lèi)型的判等是判斷棧上面引用,而不是堆上面的數(shù)據(jù),判斷兩個(gè)對(duì)象是否相等一般用Equals 2.由此可見(jiàn)引用類(lèi)型在傳遞參數(shù)的時(shí)候是直接把引用傳過(guò)去的 3.值類(lèi)型在判斷的時(shí)候是轉(zhuǎn)成同類(lèi)型再去判斷的,由進(jìn)度低的轉(zhuǎn)向進(jìn)度高的 4.因此有些時(shí)候int類(lèi)型和double類(lèi)型做計(jì)算的時(shí)候,與我們想象中的結(jié)果有些小小的偏差,系統(tǒng)自動(dòng)把int類(lèi)型轉(zhuǎn)成了double類(lèi)型做運(yùn)算的
至此文章結(jié)束,祝大家永遠(yuǎn)周末無(wú)bug有些不對(duì)的地方希望提出來(lái)相互交流。謝謝大家!!! 如有轉(zhuǎn)發(fā)請(qǐng)注明出處:博主地址:http://blog.csdn.net/mango_love
總結(jié)
以上是生活随笔為你收集整理的C#深入解析数据类型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c#枚举
- 下一篇: ssential Diagram for