发布日期:2025-03-21 09:40 点击次数:109
在咱们肃肃了解c#中的String类型前萝莉少女,先来判断一下底下代码的效能吧~
上头代码的最终输出效能是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此时照旧存储的底本的本体。咱们不错来看浅陋的图解:
萝莉少女
以上咱们不错用代码来说明咱们的论断:
不错看到最终运行的效能:
为了更好瓦解以上代码,底下是对代码的一些东西的证明:
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(),例:到此这篇对于c#中String类型的存储旨趣详解的著作就先容到这了萝莉少女,更多关联c# String类型存储本体请搜索剧本之家畴前的著作或不绝浏览底下的关联著作但愿各人以后多多守旧剧本之家!