精华内容
下载资源
问答
  • 在c#中分为值类型和引用类型,值类型为int ,float ,bool ,...为什么string引用类型呢?首先明白string指向常量空间的地址。 如果我们有一个字符串 string a="abcde"; 我们用a给其他字符串赋值:string b=a,c=a...

    在c#中分为值类型和引用类型,值类型为int ,float ,bool ,char ,struct等简单数据类型,引用类型有stirng,class。

    然而string的身为引用类型却表现得与值类型十分相同。为什么string为引用类型呢?首先明白string指向常量空间的地址。

    如果我们有一个字符串 string a="abcde";

    我们用a给其他字符串赋值:string b=a,c=a,d=a;

    那么这样子我们就得到了4个一模一样的字符串"abcde"。a  b  c  d都是指向同一块地址。

    可是既然string是引用类型,那么a ,b ,c ,d 代表的都是同一个字符串,如果我改变其中一个字符串a="1234",另外的三个由于指向的都是同一个字符串,其他三个也应该是"1234"。但是事实上并不是这样子的,另外三个的值依旧是”abcde“。这样子的话string还能叫做引用类型吗?

    答案是string当然是个引用类型。

    由于其他三个字符串我们使用 a 去赋值,在a ,b , c , d ,指向的都是同一块常量地址。但是常量是不能直接被改变的,因此我们不能通过直接修改字符串常量来达到我们修改字符串的目的,必须是开辟另一个常量空间存放新的字符常量,因此,当使用 a="1234"时,a指向的地址该变了,但是b,c,d还是指向原来的同一块空间。这种情况产生的现象使得string和值类型更改值时产生的现象一模一样(如:int k=10;int t=k;t=20;)

    引用是一种别名,本质上是指向同一块地址,底层实现是通过指针。

    展开全文
  • .Net 框架程序设计(修订版)中有这样一段描述:String类型...直接继承自Object的类型一定是引用类型,因为所有的值类型都继承自System.ValueType。值得 指出的是System.ValueType却是一个引用类型。)。   代码一:

    .Net 框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字 符串。(译注:注意这里的“直接继承”。直接继承自Object的类型一定是引用类型,因为所有的值类型都继承自System.ValueType。值得 指出的是System.ValueType却是一个引用类型。)。

     

    代码一:


    string  str1 = "string" string  str2 = "string" Console .WriteLine(string .ReferenceEquals(str1, str2));

    既 然String类型是引用类型,那么代码一输出的应该是False,然而事实上代码一输出时的是True。这是因为当CLR初始化的时,它会创建一个内部 的散列表,Key为字符串,Value为指向托管堆中字符串对象的引用。当构造str1时,先会去散列表中查询是否存在”string”字符串,如果不存 在那么会在托管堆中构造一个新的String对象,然后将”string”字符串和指向该对象的引用添加到散列表中,当构造str2时,由于散列表中存在 Key为”string”的引用,于是将Value值赋值给str2,那么str1和str2引用的是同一个String对象,代码一自然就返回True 了

    展开全文
  • 这要从string类型的内存驻留机制说起,这也CLR对其进行优化的一种方式 #region string类型特殊的内存驻留机制 //string类型的特殊之处就在于CLR之中做的相关的优化 //当有多个字符串变量包含了同样的字符串...

    这要从string类型的内存驻留机制说起,这也是CLR对其进行优化的一种方式

    #region string类型特殊的内存驻留机制
                //string类型的特殊之处就在于CLR之中做的相关的优化
                //当有多个字符串变量包含了同样的字符串实际值时,
                //CLR可能不会为它们重复地分配内存,而是让它们统统指向同一个字符串对象实例。
                string strA = "Hello";
                string strB = "Hello";
    
                Console.WriteLine(Object.Equals((Object)strA, (Object)strB));
                Console.WriteLine(Object.ReferenceEquals((Object)strA, (Object)strB));
                Console.WriteLine(strA.GetHashCode());
                Console.WriteLine(strB.GetHashCode());
    
    
                string str1 = "Hello";
                string str2 = "Hello";
                Console.WriteLine(Object.ReferenceEquals(str1, str2));
    
                //关于驻留池 字面声明的变量没有检查驻留池
                StringBuilder sbr = new StringBuilder();
                sbr.Append("He").Append("llo");
    
                string str3 = "Hello";
                string str4 = sbr.ToString();
    
                Console.WriteLine(Object.ReferenceEquals(str3, str4)); //返回false,虽然两个字符串的值相同,但是在内存中式不相同的两个引用
    
                Console.WriteLine(Object.ReferenceEquals(str3, str1));
    
                //强制CLR检查驻留池
                StringBuilder sbr2 = new StringBuilder();
                sbr2.Append("He").Append("llo");
                string str5 = "Hello";
                //在转换之后进行检查,时候有相同的字符串在内存中,如果存在,就返回一个指向它的引用
                string str6 = String.Intern(sbr2.ToString());
                Console.WriteLine(Object.ReferenceEquals(str5, str6));
    
                #endregion

    转载于:https://www.cnblogs.com/Sky-cloudless/archive/2012/05/16/2503368.html

    展开全文
  • 为什么引用类型string的行为却是值类型   分类:  C#2012-03-02 11:2464人阅读评论(0)收藏举报 首先,我们需要知道string的如下特性: 1.字符串做参数,传递的是引用,只是一个指针的复制,你修改参数的...
    
    

    为什么引用类型string的行为却是值类型       

            分类:            C#64人阅读评论(0)收藏举报
    首先,我们需要知道string的如下特性:

    1.字符串做参数,传递的是引用,只是一个指针的复制,你修改参数的指向,影响不到调用它的函数中的那个指针所指向的内容
    2.字符串不可修改。你以任何一种形式修改了字符串(+,=等操作),源字符串其实还在的,只是根据你的修改重新生成了一个新的字符串
    3.如果需要修改,两种方案,一是将修改后的字符串返回;二是作参数传字符串时使用 ref 传递,这样子函数中可以直接修改掉主函数中的指针指向,从而指向新的字符串。
    4  定义字符串时,会先查CLR内部的散列表。

      字符串类型就是一个值类型的引用类型,用c++的概念来解释的话,就是一个指针,即*pstr.
      
      *pstr = "123"; ----string中存放的是地址
      
      但是c#中做了特殊的处理,就是第2条,不能对修改pstr所指向的地址的值。当你修改*pstr的值时,其实c#并没有修改pstr所
      指的内存的值,而是重新分配了一块内存赋新的值,然后再将这块新的内存的首地址赋值给指针pstr. 正是因为这条奇怪的规  则,使得c#中的引用类型的string的行为却是值类型。

     
      对于第1条,字符串做参数时,其实就相当于c++中的指针做参数,*pstr,这样传递的都是地址。但是因为第2条的原则规则,函数内用传入的指针*pstr_input去修改值后,pstr_input指向了修改后的值的内存,而原始指针pstr还是指向原来的内存,pstr指向的内存的值和pstr_input指向的内存的值当然就不一样了。

     
      对于第3条, 当用 ref string 来传递参数时,其实就是相当于c++中的 **point指针的指针的方式了,这样传递参数的时候,参数中就是原始参数*pstr指针pstr的指针,即传递的值就是&pstr. 这样在函数中修改string时就会修改string的引用值,即修改*point的值。因为是用**point这样的指针的指针的方式,函数中的对*point的修改时可以带出去的。即函数中的修改,等于需改了主函数中的指针指向,函数中与主函数中都同时指向新的字符串。

      对于第4条,
      string str1 = "string"; string str2 = "string"; Console.WriteLine(string.ReferenceEquals(str1, str2));
      既然String类型是引用类型,那么代码一输出的应该是False,然而事实上代码一输出时的是True。这是因为当CLR初始化的时  ,它会创建一个内部的散列表,Key为字符串,Value为指向托管堆中字符串对象的引用。当构造str1时,先会去散列表中查询  是否存在”string”字符串,如果不存在那么会在托管堆中构造一个新的String对象,然后将”string”字符串和指向该对象的引  用添加到散列表中,当构造str2时,由于散列表中存在Key为”string”的引用,于是将Value值赋值给str2,那么str1和str2引  用的是同一个String对象,代码一自然就返回True了

    展开全文
  • string类型是引用类型么?为什么它的使用方法那么像值类型?你如何证明它是引用类型? 很有意思的一个问题,我后来专门以一封邮件作为了回复。 string 类型 是 引用类型 string类型与stringbuilder类型很像,...
  • 结构类型,枚举类型都是值类型;类,字符串,委托都是引用类型。 int a = 1; int b = a; a = 2; Console.WriteLine("a:{0};b:{1}", a, b);//a:2;b:1 string aa = "123"; ...
  • 稍微有点.NET 编程知识的人都知道 string是引用类型。我为什么还有此一问?因为string的使用非常像值类型。举个例子: string str = "abc"; Test(str); MessageBox.Show(str); private void Test(string str) {...
  • 引用类型引用类型变量的值一串地址,变量存储在栈中,变量的数据存储在地址所指向的堆空间中。 值类型: 值类型变量和变量的数据都存储在栈中。 当值类型的变量作为函数的形参时: 在函数内部对形参的值进行...
  • string 是值类型,还是引用类型(.net) 一.string类型的用法比较像值...稍微有点.NET编程知识的人都知道string是引用类型。我为什么还有此一问?因为string的使用非常像值类型。举个例子: stringstr="abc...
  • java 中String 是个对象,是引用类型 ,基础类型与引用类型的区别是,基础类型只表示简单的字符或数字,引用类型可以是任何复杂的数据结构 ,基本类型仅表示简单的数据类型,引用类型可以表示复杂的数据类型,还可以...
  • 不能改变状态的意思,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。   区分对象和对象的引用 对于Java初学者...
  • java 中String 是个对象,是引用类型 ,基础类型与引用类型的区别是,基础类型只表示简单的字符或数字,引用类型可以是任何复杂的数据结构 ,基本类型仅表示简单的数据类型,引用类型可以表示复杂的数据类型,还...
  •  JavaScript基本数据类型包括:undefined、null、number、boolean、string。基本数据类型是按值访问的,就是说我们可以操作保存在变量中的实际的值。 1)基本数据类型的值不可变的 任何方法都无法改变一个基本...
  • 前言在Java世界里,有这么一句话:“一切都是对象”,Java语言假设我们只进行面向对象的程序设计。Java是一种“纯粹”的面向对象程序...引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定...
  • 事实上,那本厚厚的Java书上很好的解释了这个问题—— 9.2.2 不可变字符串与限定字符串 String对象不可变的,它的内容不能改变的。...第一条语句创建了一个内容"Java"的String对象,并将其引用赋值
  • 基本数据类型 JavaScript基本数据类型包括:undefined、null、number、boolean、string。基本数据类型是按值访问的,就是说我们可以操作保存在变量中的实际的值。1)基本数据类型的值不可变的任何方法都无法改变...
  •  首先,要说明string为什么是引用类型,先来考虑下什么是引用类型,什么是值类型,以及他们的区别是什么。在网上随便搜搜基本上的解释都是,值类型存储在栈上,引用类型存储在堆上。这句话基本上
  • 一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。 final关键字的好处 final关键字提高了性能。JVM和Java应用都会缓存final变量。 final...
  • 中还有一个叫做std::numpunct的类模板,std::numpunct有一个成员函数的返回类型是std::string,所以< iostream >悄咪咪包含了string头文件,并不是string不用导包。 原答案:https://www.
  • 为什么说java只要值传递呢? 对于基本数据类型,传参传递的就是数值的副本,也就说把实参的数据复制给形参一份,不管形参怎么改变,实参是不受影响的 对于引用数据类型,传参传递的是引用的副本,也就说把引用(对象的地址...
  • <p>public class ListAddTest {<!-- --> ...<p>String是引用类型,但是list添加String[]的时候就是对象的引用,而添加String的时候就是对象的拷贝,为什么呢?</p>
  • 为什么String不可变的? String类 什么不可变对象  当满足以下条件时,对象才不可变的: 对象创建以后其状态就不能修改。 对象的所有域都final类型的。 对象正确创建的(在对象的创建期间,this引用...
  • Java String、Integet类型“==”什么时候true 先上代码: 运行结果: 分析: 1、==本身代表引用地址的比较,当“+”都常量连接时,先去String常量池去找,若有,直接返回常量池该值; 2、若“+”有变量,则会...
  • String类声明final类型,大抵从“性能”和“安全性”两方面考虑的。 不可变性支持字符串常量池 字符串的不可变性使得字符串可以存储在字符串常量池中,同一个值可以被多个变量引用,可以节省内存空间的,提高...
  • public class Area { // 区域ID ... private String areaName; // 区域权重 private Integer priority; // 区域创建时间 private Date createTime; // 区域更新时间 private Date lastEditTime;...
  • 不能改变状态的意思,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。  区分对象和对象的引用  对于Java初学者, 对于...
  • Java中的String为什么是不可变的? -- String源码分析

    万次阅读 多人点赞 2014-01-15 22:07:12
    不能改变状态的意思,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。 区分对象和对象的引用 对于Java初学

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,291
精华内容 516
关键字:

为什么string是引用类型