大家都知道,C#中的string是一个引用类型,String对象是存放在堆上,而不是堆栈上的,因此,当把一个字符串变量赋给另一个字符串时,会得到对内存中同一个字符串的两个引用。但是大家有没有想过,为什么修改其中一个字符串,另外一个不受影响呢?
  原来,当我们把一个字符串变量赋给另一个字符串时,就会创建一个全新的String对象,就是说这个时候就会有两个对象,比如:

class StringExc
{
    public static void Main()
    {
        string s1 = "original string";
        string s2 = s1; //注意此时会创建一个新对象
        Console.WriteLine( "s1 is " + s1 );
        Console.WriteLine( "s2 is " + s2 );
        s1 = "changed string";
        Console.WriteLine( "s1 is now " + s1 );
        Console.WriteLine( "s2 is now " + s2 );
    }
}

输出结果为:
s1 is original string
s2 is original string
s1 is now changed string
s2 is now original string

  也就是说,改变s1的值并没有对s2造成任何影响,这与我们平时所说的引用类型的行为正好相反。当用值"original string"初始化s1时,就在堆上分配了一个String对象。在初始化s2时,引用也指向这个对象,所以s2的值也是"original string"。但是现在要改变s1的值,而不是替换原来的值时,堆上就会为新值分配一个新对象。s2变量仍然指向原来的对象,所以它的值没有改变。

另外,如果我们像下面这样:
string str1 = "abc";
string str2 = "abc";

  当我们用System.Object.Equals(str1,str2)比较时,返回值是true;按理说str1和str2应该指向不同的空间,应该返回false才对啊。原来Equals有三个版本:

public   override   bool   Equals(object);   
public   bool   Equals(string);   
public   static   bool   Equals(string,   string); 

  前两个实例方法内部会调用CompareOrdinal静态方法,它会字符串中的各个字符,如果相等就返回true。第三个首先会检查两个引用指向的是否是同一个对象,如果是,就返回true,不再去比较各个字符了。
其实CLR使用了一种叫字符串驻留的技术,对于
string   str1="abc";
string   str2="abc";
当CLR初始化时,会创建一个内部的散列表,其中的键为字符串,值为指向托管堆中字符串的引用。刚开始,散列表为空,JIT编译器编译方法时,会在散列表中查找每一个文本常量字符串,首先会查找"abc"字符串,并且因为没有找到,编译器会在托管堆中构造一个新的指向"abc"的String对象引用,然后将"abc"字符串和指向该对象的引用添加到散列表中。
  接着,在散列表中查找第二个"abc",这一次由于找到了该字符串,所以编译器不会执行任何操作,代码中再没有其它的文本常量字符串,编译器的任务完成,代码开始执行。执行时,CLR发现第一个语句需要一个"abc"字符串引用,于是,CLR会在内部的散列表中查找"abc",并且会找到,这样指向先前创建的String对象的引用就被保存在变量s1中,执行第二条语句时,CLR会再一次在散列表中查找"abc",并且仍然会找到,指向同一个String对象的引用会被保存在变量s2中,到此s1和s2指向了同一个引用,所以System.Object.Equals(s1,s2)就会返回true了。
  另外,C#中是不允许用new操作符创建String对象的,编译器会报错。

转载于:https://www.cnblogs.com/michaelxu/archive/2008/05/06/1184385.html

C#中string类型赋值问题相关推荐

  1. Object Pascal中String类型的内幕探讨 (转)

    Object Pascal中String类型的内幕探讨 (转) 在object Pascal中,String(准确的说是AnsiString)是一种可变长度的字符串,通过PChar(AString)可 ...

  2. java语言特点 字符串不变_面试必问:Java中String类型为什么设计成不可变的?

    这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下. 想要完全了解String,在这里我们需要解决以下 ...

  3. c++ java string_C++中string类型的内部结构是什么?

    C++中string类型的内部结构是什么? string a; 为什么sizeof(a)是32? ostringstream的问题 在代码中#include 了,声明了一个ostringstream变 ...

  4. java中数组的返回值是什么类型_面试必问:Java中String类型为什么设计成不可变的?...

    这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下. 想要完全了解String,在这里我们需要解决以下 ...

  5. java string设置编码_详解Java中String类型与默认字符编码

    为什么写这个 至于为什么要写这个,主要是一句mmp一定要讲,绕了一上午,晕死 Java程序中的中文乱码问题一直是一个困扰程序员的难题,自己也不例外,早在做项目时就遇到过很多编码方式的坑,当时想填来着, ...

  6. 结构体中string类型成员

    结构体中存在string类型成员 原创 2015年12月21日 17:34:04 标签: 结构体 / string类型成员 / 构造函数 2593 #include <iostream> ...

  7. Java中String类型的概述

    String的特性 1 String类:代表字符串.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现. 2 String是一个final类,代表不可变的字 ...

  8. 使用下标给string类型赋值之后,cout输出变量为空的问题。

    今天写创建文件夹的时候,怎么创建都不会,反复修改,确定错误是出在了string类型的变量上面. 看下面代码 //这个一个函数中的代码,函数参数是string fileurl_sint len = fi ...

  9. java中字符串的创建_【转载】 Java中String类型的两种创建方式

    本文转载自 https://www.cnblogs.com/fguozhu/articles/2661055.html Java中String是一个特殊的包装类数据有两种创建形式: String s ...

最新文章

  1. GDT(全局描述符表)和LDT(局部描述符表)
  2. linux 不同ip 相同mac arp,linux – nmap和arp-scan不一致的IP-MAC结果
  3. DELL 控制卡做raid
  4. 一张图看透微信公众号、企业号、小程序
  5. 给std::string增加format函数
  6. DevOps - 用 Ansible 管理 VMware 虚拟机
  7. CCF认证-2014-12-2 Z字形扫描
  8. sql高级语法之IF、IFNULL
  9. 在家远程办公效率低?那你一定要收好这个「在家办公」神器!
  10. Keil V4安装教程
  11. [渝粤教育] 西南科技大学 翻译 在线考试复习资料
  12. python打造批量关键词排名查询工具
  13. DOM控制video实现开始/暂停按钮思路方法
  14. win10 截屏 快捷键(全屏直接保存、全屏间接保存、当前界面)
  15. 古希腊的对外战争,兼谈希腊罗马的军制和战斗力
  16. BZOJ 4816[SDOI2017]数字表格(莫比乌斯反演)
  17. Oracle Golden Gate
  18. mac装linux iso不用u盘安装,在任何mac上用u盘安装OSX和Windows10双系统的方法(支持老电脑、不用Bootcamp)...
  19. MPEG-2压缩编码技术原理应用
  20. 天池AI学习全面升级,所有学习资源都给你你汇总好啦!

热门文章

  1. Python数据结构——栈、队列的实现(一)
  2. addView的误区
  3. Qt控件注册事件过滤器后不显示
  4. Android 菜单选项动态变化
  5. NetApp SE 实验室报告:SAN Boot with VMware ESX 3.0.0
  6. Android ListView滑动后背景变黑
  7. android ListView 局部刷新
  8. android 获取apk中的素材图片
  9. 解决 Successfully created project '' on GitHub, but initial push failed: Could not read from remote re
  10. 【牛客网多校】19-7-25-H题 Magic Line