最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c#中String類型的存儲原理詳解

 更新時(shí)間:2022年04月01日 15:51:33   作者:Green_756  
本文主要介紹了c#中String類型的存儲原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在我們正式了解c#中的String類型前,先來判斷一下下面代碼的結(jié)果吧~

String str1 = "123";
String str2 = str1;
str2 = "321";
Console.WriteLine(str1);

上面代碼的最終輸出結(jié)果是123,如果有淺學(xué)過引用類型的同學(xué)一定會問:str2不是在存儲的是str1的引用么?那么str2不是和str1指向堆中同一塊內(nèi)存空間么?為什么在引用了str2使其改變數(shù)據(jù)后再打印出str1最終還是打印出來123?

這也是我最初的疑問,但不要著急,一步一步看下去,相信很快能了解清楚。

在正式開始之前,我們先了解一下c#中的內(nèi)存分區(qū):

內(nèi)存分區(qū)

  • 棧區(qū):由編譯器自動分配釋放 ,存放值類型的對象本身,引用類型的引用地址(指針),靜態(tài)區(qū)對象的引用地址(指針),常量區(qū)對象的引用地址(指針)等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
  • 堆區(qū)(托管堆):用于存放引用類型對象本身。在c#中由.net平臺的垃圾回收機(jī)制(GC)管理。棧,堆都屬于動態(tài)存儲區(qū),可以實(shí)現(xiàn)動態(tài)分配。
  • (重點(diǎn)看)靜態(tài)區(qū)及常量區(qū):用于存放靜態(tài)類,靜態(tài)成員(靜態(tài)變量,靜態(tài)方法),常量的對象本身。由于存在棧內(nèi)的引用地址都在程序運(yùn)行開始最先入棧,因此靜態(tài)區(qū)和常量區(qū)內(nèi)的對象的生命周期會持續(xù)到程序運(yùn)行結(jié)束時(shí),屆時(shí)靜態(tài)區(qū)內(nèi)和常量區(qū)內(nèi)對象才會被釋放和回收(編譯器自動釋放)。所以應(yīng)限制使用靜態(tài)類,靜態(tài)成員(靜態(tài)變量,靜態(tài)方法),常量,否則程序負(fù)荷高。
  • 代碼區(qū):存放函數(shù)體內(nèi)的二進(jìn)制代碼。

在c#中,String的存儲方式很特殊,在c#的內(nèi)存中,在常量區(qū)里會分配一塊空間叫做String暫存池(常量池),在某些時(shí)候,我們的字符串?dāng)?shù)據(jù)是存儲在這個(gè)常量池中的,而地址依然是存放在棧中。

例如用 String str = "xXXXX" 的方式來創(chuàng)建String變量的話,那么String的值便會存儲在String常量池中,在我們以這種方式創(chuàng)建String變量時(shí),編譯器會先判斷你這個(gè)內(nèi)容有沒有已經(jīng)在常量池出現(xiàn)過了,如果已經(jīng)出現(xiàn)過,那么不會再在常量池中使用空間來存放一個(gè)相同的內(nèi)容,這個(gè)內(nèi)容只會固定有一個(gè)引用,所以在創(chuàng)造相同內(nèi)容的String的時(shí)候,他們的引用都是相同的。又有一種情況:一開始A和B內(nèi)容相同,就是說A與B的引用都相同時(shí),此時(shí)將B的內(nèi)容更改,那么B的內(nèi)容在常量池中就會使用另一塊空間,那么相應(yīng)的B的引用也會改變,而A的引用并不會改變,因?yàn)锳此時(shí)還是存儲的原來的內(nèi)容。我們可以來看簡易的圖解:

以上我們可以用代碼來證實(shí)我們的結(jié)論:

String str1 = "123";
            String str2 = "123";
            Console.WriteLine("此時(shí)還未將str1中的值做改變:");
            if(object.ReferenceEquals(str1,str2))
            {
                Console.WriteLine("此時(shí)引用相同");
            }
            else
            {
                Console.WriteLine("此時(shí)引用不相同");
            }
            if (object.ReferenceEquals(String.Intern(str1), String.Intern(str2)))
            {
                Console.WriteLine("此時(shí)存儲在同一塊常量池中,且引用相同");
            }
            else
            {
                Console.WriteLine("此時(shí)兩字符串不相同,存在不同的空間中,且引用也不同");
            }
 
            Console.WriteLine();
            str1 = "12";
            Console.WriteLine("此時(shí)將str1的值改變,比較str1與str2的引用和所指向的內(nèi)存空間是否相同:");
 
            if (object.ReferenceEquals(str1, str2))
            {
                Console.WriteLine("此時(shí)引用相同");
            }
            else
            {
                Console.WriteLine("此時(shí)引用不相同");
            }
            if (object.ReferenceEquals(String.Intern(str1), String.Intern(str2)))
            {
                Console.WriteLine("此時(shí)存儲在同一塊常量池中,且引用相同");
            }
            else
            {
                Console.WriteLine("此時(shí)兩字符串不相同,存在不同的空間中,且引用也不同");
            }

可以看到最終運(yùn)行的結(jié)果:

為了更好理解以上代碼,下面是對代碼的一些東西的解釋:

object.ReferenceEquals

這個(gè)是用來比較兩個(gè)變量的引用是否一樣,如果一樣,那么則會返回true,否則將會返回false。

String.Intern

String.Intern的工作方式很好理解,你將一個(gè)字符串作為參數(shù)使用這個(gè)接口,如果這個(gè)字符串已經(jīng)存在池中,就返回這個(gè)存在的引用;如果不存在就將它加入到池中,并返回引用。

 當(dāng)然,以上只是針對用String str = "XXXXX";這樣創(chuàng)建變量的方式來討論的,那么什么時(shí)候創(chuàng)建String會考慮這樣的問題呢?下面來看情況總結(jié):

我們要知道不是所有字符串都放在常量池當(dāng)中:

存放暫存池:

  • 用字面量值創(chuàng)建String對象,例:String str = "ABCD";
  • 用String.Intern(),例:StringBuilder sb = new StringBuilder(“ABCD”);string str1 = “ABCD”;string str2=string.Intern(sb.ToString);
  • 字符串拼接,例:str1 = "ABCD";str2 = "EFG";str1+str2。

不存放暫存池(存放在堆中):

  • 使用str.Tostring,例:str1 = "ABCD";str2 = str1.ToString();
  • 使用char[].Tostring(),例:str1=ABCD”; char[]charArray = str1.ToArray(); str2 = charArray.ToString();
  • 使用new String(),例:
str1=”999”;char[] charArray = str1.ToArray();string str2 = new string(charArray);string str3 = new string(charArray);

char[] charArray = {‘A','B'};str1 = “ABCDE”;str2 =”CDE”+charArray.Tostring();

char[] charArray1 = {‘A','B'};char charArray2 = {‘C','D','E'};

str1 =”ABCDE”;str2=charArray1.ToString()+charArray2.ToString();

到此這篇關(guān)于c#中String類型的存儲原理詳解的文章就介紹到這了,更多相關(guān)c# String類型存儲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • .NET企業(yè)級項(xiàng)目中遇到的國際化問題和解決方法

    .NET企業(yè)級項(xiàng)目中遇到的國際化問題和解決方法

    這篇文章主要介紹了.NET企業(yè)級項(xiàng)目中遇到的國際化問題和解決方法,說明了理國際化問題的一些典型例子和經(jīng)驗(yàn)之談,需要的朋友可以參考下
    2014-07-07
  • c#委托把方法當(dāng)成參數(shù)(實(shí)例講解)

    c#委托把方法當(dāng)成參數(shù)(實(shí)例講解)

    本篇文章主要是對c#委托把方法當(dāng)成參數(shù)的實(shí)例代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • C#原型模式之如何通過克隆對象來優(yōu)化創(chuàng)建過程

    C#原型模式之如何通過克隆對象來優(yōu)化創(chuàng)建過程

    原型模式是一種創(chuàng)建型設(shè)計(jì)模式,通過克隆現(xiàn)有對象來創(chuàng)建新對象,避免重復(fù)的創(chuàng)建成本和復(fù)雜的初始化過程,它適用于對象創(chuàng)建過程復(fù)雜、需要大量相似對象或避免重復(fù)初始化的場景,本文介紹C#原型模式之如何通過克隆對象來優(yōu)化創(chuàng)建過程,感興趣的朋友一起看看吧
    2025-03-03
  • 基于C#實(shí)現(xiàn)一個(gè)最簡單的HTTP服務(wù)器實(shí)例

    基于C#實(shí)現(xiàn)一個(gè)最簡單的HTTP服務(wù)器實(shí)例

    這篇文章主要介紹了基于C#實(shí)現(xiàn)一個(gè)最簡單的HTTP服務(wù)器的方法,詳細(xì)分析了http服務(wù)器的實(shí)現(xiàn)原理與相關(guān)技巧,以及對應(yīng)的注意事項(xiàng),需要的朋友可以參考下
    2014-12-12
  • C#?CM框架實(shí)現(xiàn)多頁面管理的實(shí)例代碼

    C#?CM框架實(shí)現(xiàn)多頁面管理的實(shí)例代碼

    這篇文章主要介紹了C#?CM框架下一行代碼實(shí)現(xiàn)多頁面管理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • C#使用CefSharp控件實(shí)現(xiàn)爬蟲

    C#使用CefSharp控件實(shí)現(xiàn)爬蟲

    這篇文章介紹了C#使用CefSharp控件實(shí)現(xiàn)爬蟲的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • C#中枚舉的特性 FlagAttribute詳解

    C#中枚舉的特性 FlagAttribute詳解

    說到FlagsAttribute,源自前幾天看到了一小段代碼,大概意思就是根據(jù)航班政策來返回哪些配送方式是否可用,根據(jù)這些是否可用來隱藏或者開啟界面的相關(guān)配送方式,不是非常明白,于是今天我們就來詳細(xì)探討下這個(gè)問題
    2018-03-03
  • C#中定時(shí)任務(wù)被阻塞問題的解決方法

    C#中定時(shí)任務(wù)被阻塞問題的解決方法

    這篇文章主要給大家介紹了關(guān)于C#中定時(shí)任務(wù)被阻塞問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用c#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Unity實(shí)現(xiàn)倒計(jì)時(shí)功能

    Unity實(shí)現(xiàn)倒計(jì)時(shí)功能

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)倒計(jì)時(shí)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 使用C# 的webBrowser寫模擬器時(shí)的javascript腳本調(diào)用問題

    使用C# 的webBrowser寫模擬器時(shí)的javascript腳本調(diào)用問題

    這篇文章主要介紹了C# 的webBrowser寫模擬器時(shí)的javascript腳本調(diào)用問題,需要的朋友可以參考下
    2017-07-07

最新評論

华池县| 丰宁| 定西市| 伊吾县| 多伦县| 黑龙江省| 城口县| 萍乡市| 泾源县| 穆棱市| 桂阳县| 云南省| 松桃| 德昌县| 张家口市| 通道| 始兴县| 稻城县| 林甸县| 锦屏县| 聂拉木县| 百色市| 莱阳市| 益阳市| 淮安市| 乌审旗| 汉源县| 五原县| 大埔县| 安平县| 梅河口市| 乌海市| 西平县| 钟祥市| 滨州市| 津市市| 柳州市| 无棣县| 上高县| 长乐市| 荥阳市|