• 探索C#字符串


    一、前言

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

    二、字符串特性

    1. 引用类型的字符串
      C#中我们都知道,引用类型是分配在堆上的,值类型分配在栈上,但引用类型的地址分配在栈上。字符串作为一种“特殊”的引用类型,并不会因为它的特殊性,将它分配到栈上去,它依旧在堆上.

    2. 字符串池
      编译器编译源码时,会将字面值字符串嵌入到托管模块的元数据中,为了减小文件大小,编译器只在模块元数据中将该字符串写入一次,引用该字符串的代码全都指向同一位置,因此一个程序中相同的字面值字符串只会存在一个实例.


    3. 字符串留用
      前面说到,一个程序相同的字面值字符串只会存在一个实例,那么非字面值字符串也会只有一个实例吗?

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

    4. 字符串的不可变性
      字符串是不可变更的,若发生变化则创建新的实例。从下图可看出,变量str加上字面值字符串“a”之后,变量str指向的堆地址发生了变化。

    5. “特殊”的字符串
      字符串是一种“特殊”的引用类型,在作为参数传递被修改后原始字符串不发生变化

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

  • 相关阅读:
    linux 日常命令
    apache2 修改默认php版本
    centos 6.5 创建守护进程
    ubuntu18.04 Yii2.0 安装yii2-queue并在Linux启动守护进程监听消息设置
    Ubuntu18.04 使用 deepinwine 安装企业微信后无法查看图片/头像/登陆二维码的解决方法
    CentOS 8安装Redis的两种方式
    如何在ubuntu 18.04中升级python 3.6到3.7
    Navicat 15 premium AppImage格式激活
    爬取彼岸图网实例
    requests库的介绍及get请求 + 小案例
  • 原文地址:https://www.cnblogs.com/kai364/p/6512559.html
Copyright © 2020-2023  润新知