91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

c#中String類型的存儲原理是什么

發布時間:2022-04-02 09:12:05 來源:億速云 閱讀:157 作者:iii 欄目:開發技術

這篇文章主要介紹了c#中String類型的存儲原理是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇c#中String類型的存儲原理是什么文章都會有所收獲,下面我們一起來看看吧。

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

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

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

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

在正式開始之前,我們先了解一下c#中的內存分區:

內存分區

  • 棧區:由編譯器自動分配釋放 ,存放值類型的對象本身,引用類型的引用地址(指針),靜態區對象的引用地址(指針),常量區對象的引用地址(指針)等。其操作方式類似于數據結構中的棧。

  • 堆區(托管堆):用于存放引用類型對象本身。在c#中由.net平臺的垃圾回收機制(GC)管理。棧,堆都屬于動態存儲區,可以實現動態分配。

  • (重點看)靜態區及常量區:用于存放靜態類,靜態成員(靜態變量,靜態方法),常量的對象本身。由于存在棧內的引用地址都在程序運行開始最先入棧,因此靜態區和常量區內的對象的生命周期會持續到程序運行結束時,屆時靜態區內和常量區內對象才會被釋放和回收(編譯器自動釋放)。所以應限制使用靜態類,靜態成員(靜態變量,靜態方法),常量,否則程序負荷高。

  • 代碼區:存放函數體內的二進制代碼。

在c#中,String的存儲方式很特殊,在c#的內存中,在常量區里會分配一塊空間叫做String暫存池(常量池),在某些時候,我們的字符串數據是存儲在這個常量池中的,而地址依然是存放在棧中。

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

c#中String類型的存儲原理是什么

c#中String類型的存儲原理是什么

以上我們可以用代碼來證實我們的結論:

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

可以看到最終運行的結果:

c#中String類型的存儲原理是什么

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

object.ReferenceEquals

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

String.Intern

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

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

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

存放暫存池:

  • 用字面量值創建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();

關于“c#中String類型的存儲原理是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“c#中String類型的存儲原理是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

芜湖县| 神木县| 德阳市| 太白县| 海口市| 冀州市| 内黄县| 文水县| 舞钢市| 耿马| 洞头县| 芒康县| 栖霞市| 碌曲县| 绥棱县| 金门县| 桂阳县| 广南县| 湟源县| 科尔| 靖边县| 榆树市| 额尔古纳市| 喀喇| 墨脱县| 元谋县| 屏山县| 山东省| 抚顺市| 花莲县| 永兴县| 绥中县| 三台县| 方山县| 岳普湖县| 弥勒县| 瓮安县| 德安县| 青川县| 芜湖市| 黄冈市|