一、前言

  刚接触C#时,书上说string是一种特殊的引用类型,因此string类型变量在作为参数传递到另一个方法,被修改后原变量的值不会发生变化,当时看得我一脸懵逼,什么叫特殊...。后来又听说字符串是不可变的(immutable),也就是说字符串一经创建便不能更改。今天就来探究一下所谓的特殊到底特殊在哪里,借助的手段是通过VS及时窗口查看变量堆栈地址(&VariableName).

二、字符串特性

  1. 引用类型的字符串
    C#中我们都知道,引用类型是分配在堆上的,值类型分配在栈上,但引用类型的地址分配在栈上。字符串作为一种“特殊”的引用类型,并不会因为它的特殊性,将它分配到栈上去,它依旧在堆上.
  2. 字符串池
    编译器编译源码时,会将字面值字符串嵌入到托管模块的元数据中,为了减小文件大小,编译器只在模块元数据中将该字符串写入一次,引用该字符串的代码全都指向同一位置,因此一个程序中相同的字面值字符串只会存在一个实例.
  3. 字符串留用
    前面说到,一个程序相同的字面值字符串只会存在一个实例,那么非字面值字符串也会只有一个实例吗?

    由上图可以看出,相同的非字面值字符串堆地址是不一样的,若想只存在一个副本可通过暂存池(如果应用程序不在保持对原始字符串的引用,GC就可释放那个字符串的内存),详情请看NSDN:String.Intern

  4. 字符串的不可变性
    字符串是不可变更的,若发生变化则创建新的实例。从下图可看出,变量str加上字面值字符串“a”之后,变量str指向的堆地址发生了变化。
  5. “特殊”的字符串
    字符串是一种“特殊”的引用类型,在作为参数传递被修改后原始字符串不发生变化

    从上图可以看出,strValue跟mStrValue的堆地址是一致的,也就是说字符串传参跟普通引用类型传参是一样的,都是传入的引用地址。那么问题来了,既然地址都传进去了,为什么字符串修改后原字符串不发生变化呢?原因就在上一条,字符串的不可变性,当方法中的字符串变量值发生变化后,字符串变量将会指向一个新的地址,原地址的值不变,因此原字符串的值不会发生变化。

探索C#字符串的更多相关文章

  1. Qt5字符串编码转换学习

    目录 1.通过Python3示例探索常用字符串编码 UTF8 ANSI Unicode 小结 2.Qt5中使用QTextCodec进行编码转换 小结 1.通过Python3示例探索常用字符串编码 下面 ...

  2. PHP内核探索之变量(7)- 不平凡的字符串

    切,一个字符串有什么好研究的. 别这么说,看过<平凡的世界>么,平凡的字符串也可以有不平凡的故事.试看: (1)       在C语言中,strlen计算字符串的时间复杂度是?PHP中呢? ...

  3. C# 字符串拼接性能探索

    本文通过ANTS Memory Profiler工具探索c#中+.string.Concat.string.Format.StringBuilder.Append四种方式进行字符串拼接时的性能. 本文 ...

  4. C# 字符串拼接性能探索 c#中+、string.Concat、string.Format、StringBuilder.Append四种方式进行字符串拼接时的性能

    本文通过ANTS Memory Profiler工具探索c#中+.string.Concat.string.Format.StringBuilder.Append四种方式进行字符串拼接时的性能. 本文 ...

  5. 对上次“对字符串进行简单的字符数字统计 探索java中的List功能 ”程序,面向对象的改进

    之前的随笔中的程序在思考后发现,运用了太多的static 函数,没有将面向对象的思想融入,于是做出了一下修改: import java.util.ArrayList; import java.util ...

  6. 对字符串进行简单的字符数字统计 探索java中的List功能

    题目: 统计一个字符串中数字和字符串的个数,并分别进行排列,要求 1.数字,字符串可以从键盘获取. 2.储存在list 3.统计数字个数,字符串个数 4.把数字和字符串按从小到大的顺序输出 5.不能使 ...

  7. 【C语言探索之旅】 第二部分第四课:字符串

    内容简介 1.课程大纲 2.第二部分第四课: 字符串 3.第二部分第五课预告: 预处理 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. ...

  8. Java探索之旅(13)——字符串类String

    1.初始化 String类是Java预定义类,非基本类型而是引用类型. public class StudyString { public static void main(String[] args ...

  9. Java探索之旅(10)——数组线性表ArrayList和字符串生成器StringBuffer/StringBuilder

    1.数组线性表ArrayList 数组一旦定义则不可改变大小.ArrayList可以不限定个数的存储对象.添加,插入,删除,查找比较数组更加容易.可以直接使用引用类型变量名输出,相当于toString ...

随机推荐

  1. Emergency(山东省第一届ACM程序设计真题+Floyd算法变型)

    题目描述 Kudo’s real name is not Kudo. Her name is Kudryavka Anatolyevna Strugatskia, and Kudo is only h ...

  2. element-ui2源码修改小问题

    最近element-ui升级到2了,添加了不少功能,可喜可贺,可喜可贺! 然而,产品的需求依然那么刁钻,上传与删除图片还是要去改源码,为了同时用新的ele,决定在2中改源码 然而,遇到问题了. 一开始 ...

  3. ASP.NET开发,从二层至三层,至面向对象 (5)

    此是一系列博文,最后一篇了.也是面向初学者而作,望你们能有更好,更多对ASP.NET面向对编程了解与认识. 前一篇中<ASP.NET开发,从二层至三层,至面向对象 (4)>http://w ...

  4. 解决MVC应用程序数据重复加载问题

    先来看看这个动画: 这是使用jQuery来实现数据加载,每点击一次,数据就加载一次.这源程序与实现来自<MVC应用程序JsonResult()的练习>http://www.cnblogs. ...

  5. MVC之——Razor语法

    实例产品基于asp.net mvc 5.0框架,源码下载地址:http://www.jinhusns.com/Products/Download View里所有以@开头或@(/*代码*)的部分代码都会 ...

  6. uni-app初体验及打包成apk

    首先用HBuilderX新建建一个uni-app项目 新建一个目录ucenter,该目录下新建两个vue文件ucenter.vue和setting.vue ucenter.vue <templa ...

  7. WebServer搭建过程

    第一步,新建Web网站项目 第二步: 右击项目解决方案,选择添加新建项 选择Web服务项 第三步,在asmx方法中将Hello World注释掉,然后编写自己的方法,这里根据项目的不同可以做不同的处理 ...

  8. Mybatis插件开发

    前面几篇文章介绍了Mybtis中四个重要的对象,其中提到它们都是在Configuration中被创建的,我们一起看一下创建四大对象的方法,代码如下所示: public ParameterHandler ...

  9. JSP学习笔记(6)-使用数据库

    1.连接MySQL数据库 1.1.JDBC JDBC(Java Database Connectivity)提供了访问数据库的API,由一些Java类和接口组成,是Java运行平台核心库中的一部分.用 ...

  10. POJ2236(KB5-A)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28617   Accepted: 118 ...