当前位置:编程学习 > C#/ASP.NET >>

string 赋值问题

string a = “adfasdf”;这个会重新new一个string对象,
string b = a;b也会重新new一个string对象吗? --------------------编程问答-------------------- 会的 --------------------编程问答-------------------- 来看星星... --------------------编程问答-------------------- 我的回答是:不会 --------------------编程问答-------------------- 我感觉也不会,b应该只是指向a。
不过不知道string类型的对象和其他对象有没有什么区别,要是没有区别的话,应该是这样的吧? --------------------编程问答-------------------- 应该不会。
b引用系统内存到给a分配的那块空间 --------------------编程问答-------------------- string类型的对象和其他类型的对象不同在于string都是只读的
但在这个例子中,这个赋值只是增加了指向同一个对象的一个引用 --------------------编程问答-------------------- 堆和栈的问题,应该是不会! --------------------编程问答-------------------- 不会,
b只是指向了a的内存地址 --------------------编程问答-------------------- 不会, .net用散列表保存字符串,当新创建一个字符串的时候,会去散列表中检测这个字符串是不是存在,如果存在返回已经存在的内存地址中的字符串,这样做显然不会创建一个新的字符串

但是如果这样

string a = “adfasdf”;这个会重新new一个string对象, 
string b ="adf";
b+="asdf";

这时候 string.ReferenceEquals(a, b) 返回false;
因为b创建了两个字符串 "adf"和"asdf"
--------------------编程问答-------------------- 不会的。

是指向内存区域。! --------------------编程问答--------------------  b 引用了 a在内存中的地址..并没有在内存中分配区域.. --------------------编程问答-------------------- 不会的
a跟b指向的是同一引用地址。不是值的副本。 --------------------编程问答-------------------- 不会的
a跟b指向的是同一引用地址。不是值的副本。 --------------------编程问答-------------------- 不会,只是引用了该对象 --------------------编程问答-------------------- 应该不会.
首先,系统申请一个内存"adfasdf",
然后a指向这个内存,
b又指向a,
实际上a和b都是指向的"adfasdf",或者你可以认为"adfasdf"的内存是个静态的.
假如你再string c = "adfasdf"; 那么系统不会在重新申请一个内存,而是用刚才的那个内存"adfasdf".
这样,a,b,c都指向的"adfasdf". --------------------编程问答-------------------- 呵呵,这么多人回答,谢谢了

我也认为不会,不过刚刚我一同事说只要string赋值都会,既然有人这么说,那么就有疑问在,所以干脆发个帖子问问大家了,很久也没来csdn,也过来看看了,呵呵 --------------------编程问答-------------------- 应该是重新构造了一个新的string对象:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a="asdfg";
string b=a;
cout<<a<<endl;
cout<<b<<endl;
a[1]='z';
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
运行这段代码,可以发现改变a的值后b的值并没有变化,所以说a和b并不是指向的同一个string对象,在运行b=a的同时又重新构造了一个新的对象给了b。 --------------------编程问答-------------------- 看了这个帖子很有人气,顺便打个广告

公司正在招人,c#开发方面的,包括前台(winform,webform, silverlgiht),后台程序开发,以及测试
工作年限3年以上,待遇6k-10k

有意者请将简历发到我的邮箱,lakiew@gmail.com

公司在上海,做美国证券交易平台的,可以上www.sogotrade.com看看

现在是金融危机时期,有招聘职位对很多人来说是件好事,希望斑竹不要认真,删我的贴啊。

--------------------编程问答--------------------
引用 17 楼 whutsusan 的回复:
应该是重新构造了一个新的string对象: 
#include <iostream> 
#include <string> 
using namespace std; 
int main() 

string a="asdfg"; 
string b=a; 
cout < <a < <endl; 
cout < <b < <endl; 
a[1]='z'; 
cout < <a < <endl; 
cout < <b < <endl; 
return 0; 

运行这段代码,可以发现改变a的值后b的值并没有变化,所以说a和b并不是指向的同一个string对象,在运行b=a的同时又重新构造了一个新的对象给…


是c#语言 --------------------编程问答-------------------- 我认为是重新构造了一个新的string对象

string对象好像是每被赋值一次就会 重构一个对象

 
  
//这个例子   这种情况 别人后会用StringBuilder 来做
   string s = "";
      for(int i = 0;i<10;i++)
      {
        s+=i.ToString();
      }

别人都会用
      StringBuilder str = new StringBuilder();
      for(int i = 0;i<10;i++)
      {
         str.Append(i.ToString());
      }
--------------------编程问答-------------------- ls的例子不合适 --------------------编程问答--------------------
引用 17 楼 whutsusan 的回复:
应该是重新构造了一个新的string对象: 
#include <iostream> 
#include <string> 
using namespace std; 
int main() 

string a="asdfg"; 
string b=a; 
cout < <a < <endl; 
cout < <b < <endl; 
a[1]='z'; 
cout < <a < <endl; 
cout < <b < <endl; 
return 0; 

运行这段代码,可以发现改变a的值后b的值并没有变化,所以说a和b并不是指向的同一个string对象,在运行b=a的同时又重新构造了一个新的对象给…


同意!

string a = "this is a";
string b = a;
b = "this is b";
Label1.Text = a;

猜猜Label1.Text的值是啥?













错了吧~ 是“this is a” --------------------编程问答-------------------- 象这种情况的重新生成对象是因为string是只读的,一个string一旦生成就不可以再更改,所以这种形式的赋值必然导致生成新对象。

而lz的例子中,并没有可以导致string的值需要发生变化的操作,所以,这种情况下,不会生成新的string对象。 --------------------编程问答-------------------- 哦 My God 我上面说的等于没说........看的人跳过吧 --------------------编程问答-------------------- 倒... --------------------编程问答-------------------- 日 都搞糊涂了.........


有人这么说:

string的值永远不会改变!
String a = "a";//假设a指向地址0x0001,
a = "b";//重新负值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的。
从表面上看String类型的对象改变了值,但事实是他不能改变值,只能改变指向的地址


有人这么说:

对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
String 是final类,即不能被继承.

并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.
这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的. 


这两个说法是一回事吗??????????????????都搞糊涂了

到底是改变地址  还是重新创建一个了.......... --------------------编程问答-------------------- 一回事,说法不同而已... --------------------编程问答--------------------
引用 23 楼 dancingbit 的回复:
象这种情况的重新生成对象是因为string是只读的,一个string一旦生成就不可以再更改,所以这种形式的赋值必然导致生成新对象。 

而lz的例子中,并没有可以导致string的值需要发生变化的操作,所以,这种情况下,不会生成新的string对象。


LZ请参考这位的回答吧~ --------------------编程问答-------------------- 重新创建了新的string对象,引用所指向的地址自然会改变...
嗯,a是一个引用... --------------------编程问答-------------------- 不会,
我经常这样干 --------------------编程问答-------------------- string a ="a"; //a的内存地址在0x0001开始1位
string b =  a; //b的内存地址是0x0001开始1位

a="b"; //a的地址是0x0002开始1位,b的地址是0x0001开始1位
b="c"; //a的地址是0x0002开始1位,b的地址是0x0003开始1位

b=a;   //a的地址是0x0002开始1位,b的地址是0x0002开始1位
--------------------编程问答--------------------  搞了这么就 这么简单的代码都没搞明白是怎么回事

引用楼主 tmxk2002 的帖子:
string a = “adfasdf”;这个会重新new一个string对象, 
string b = a;b也会重新new一个string对象吗?
--------------------编程问答-------------------- 菜鸟来报道 --------------------编程问答--------------------
引用 32 楼 wxm3630478 的回复:
 搞了这么就 这么简单的代码都没搞明白是怎么回事 

引用楼主 tmxk2002 的帖子:
string a = “adfasdf”;这个会重新new一个string对象, 
string b = a;b也会重新new一个string对象吗? 

不会 --------------------编程问答--------------------
引用 16 楼 tmxk2002 的回复:
不过刚刚我一同事说只要string赋值都会

赞同。
赋值就是一个方法而已,string虽然是引用类型,但是在该方法中都会重新分配一个内存(深度复制,而不是简单的指向地址)。 --------------------编程问答-------------------- 貌似没人看见你的招聘贴,我工作半年,路过。 --------------------编程问答-------------------- --------------------编程问答-------------------- 想知道会不会,试一下就知道了

            string a = "ojlovecd";
            string b = a;
            Console.WriteLine(a == b);
            Console.WriteLine((object)a == (object)b);


输出当然是True True了
虽然string是比较特殊的引用类型,但归根结底还是引用类型,string b = a;只是把a的引用给了b,也就是它们都指向同一块内存空间。
MSDN中讲String 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 String 对象的方法实际上是返回一个包含修改内容的新 String 对象。
也就是说,只有在修改string对象的值的时候,才会重新创建一个string对象,在楼主这个例子中,只是把a的引用给了b,并没有修改a所指向的string对象,所以不会重新创建的 --------------------编程问答-------------------- 公说公有理  婆说婆有理........道理谁有理......继续关注中......... --------------------编程问答--------------------
引用 38 楼 ojlovecd 的回复:
想知道会不会,试一下就知道了 

C# code
            string a = "ojlovecd";
            string b = a;
            Console.WriteLine(a == b);
            Console.WriteLine((object)a == (object)b);




输出当然是True True了 
虽然string是比较特殊的引用类型,但归根结底还是引用类型,string b = a;只是把a的引用给了b,也就是它们都指向同一块内存空间。 
MSDN中讲String 对象称为不可变的(只读),…


大侠的回答很有说服力~~ --------------------编程问答-------------------- 修改字符串,就会创建一个新的字符串对象。 
c#高级编程原话 --------------------编程问答--------------------

    string a = "123";
    string b;  //内存中是怎么处理b的????????????
    private void button1_Click(object sender, EventArgs e)
    {
      if(b == null)
      MessageBox.Show("is null");
      b = a;  //可不可以认为是不重新赋值了呢?????????
      MessageBox.Show(b);
    }

//没研究过..............这些东西
--------------------编程问答--------------------
引用 42 楼 wxm3630478 的回复:
C# codestringa="123";stringb;//内存中是怎么处理b的????????????privatevoidbutton1_Click(objectsender, EventArgs e)
    {if(b==null)
      MessageBox.Show("is null");
      b=a;//可不可以认为是不重新赋值了呢?????????MessageBox.Show(b);
    }//没研究过..............这些东西


对于你这个例子,我给出以下详细解释:

    string a = "123";//在托管堆中创建一个string对象,值为123,a为指向这个对象的一个引用
    string b;  //由于没有为b赋初值,所以b不指向任何内存空间
    private void button1_Click(object sender, EventArgs e)
    {
      if(b == null)
      MessageBox.Show("is null");
      b = a;  //此处由于string是引用类型,所以为b传递的是a引用的一个副本,同样指向值为"123"的那个string对象,也就是说a和b是指向同一个对象的不同引用
      MessageBox.Show(b);
    }

--------------------编程问答-------------------- 我 
C# 数据类型有两种啊  
值类型和引用类型 
string a = “adfasdf”; 这个已经new 了2 个对象了  --------------------编程问答-------------------- 虽然string是比较特殊的引用类型,但归根结底还是引用类型,string b = a;只是把a的引用给了b,也就是它们都指向同一块内存空间。 
MSDN中讲String 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 String 对象的方法实际上是返回一个包含修改内容的新 String 对象。 
也就是说,只有在修改string对象的值的时候,才会重新创建一个string对象,在楼主这个例子中,只是把a的引用给了b,并没有修改a所指向的string对象,所以不会重新创建的



怎样才叫修改string对象的值??????????????????

b=a;  不是修改了b的值了吗 ????

string b = "";
b = "123";  //这是修改string对象的值  重新创建一个string对象???

string a = "123";
string b = a;  //这个只是把a指向值的地址给了b,没有重新创建对象吗????

string a = "123";
string b = "";
b = a;      //.................这个又怎么说???
--------------------编程问答-------------------- 绝对会的!
看代码:
            string a = "abc";
            string b = a;
            Console.WriteLine("a = {0}, b = {1}", a, b);
            a = "efg";
            Console.WriteLine("a = {0}, b = {1}", a, b);

输出结果是:
a = abc, b = abc
a = efg, b = abc

显然b不是什么指向a的指针,而是一个新的string.

string b = a;
等价于
string b;
b = a;

明白了吗? --------------------编程问答-------------------- LS 兄弟的例子我也刚想到

按照上面的说法  
a = "efg";  a 重新创建对象了 换了一个地址0x0002

但是a原来的0x0001 地址所指的值还在 b依然是用0x0001

有什么办法把a给销毁掉...........就可以看出来了 --------------------编程问答-------------------- b=a;是将a引用的一个副本传给b,也就是将a与b都指向同一个对象

string b = "";//创建一个string对象,暂称为s1,值为空字符串,b指向这个s1
b = "123";  //再次创建一个string对象,暂称为s2,值为123,b不再指向s1,改为指向s2,如果s1再没有被其他变量引用,则GC会将它回收掉

string a = "123";//创建一个string对象,暂称为s1,值为123,a指向这个s1
string b = a;  //把a的一个副本赋值给b,b也指向s1,

string a = "123";//创建一个string对象,暂称为s1,值为123,a指向这个s1
string b = "";//创建一个string对象,暂称为s2,值为空字符串,b指向这个s1
b = a;      //b不再指向s2,改为指向s1,如果s2再没有被其他变量引用,则GC会将它回收掉


--------------------编程问答-------------------- 刚没看各位大虾的评论,写了个小程序,仔细一想,有问题。
直接比较b == a就知道,b和a是指向同一个内存地址的,但这里算不算new了一个string呢?
如果把语句 string b = a;
分解成 string b;  //这里算不算new了一个string????
b = a;
应该没问题吧。

引用 46 楼 popnet 的回复:
绝对会的! 
看代码: 
            string a = "abc"; 
            string b = a; 
            Console.WriteLine("a = {0}, b = {1}", a, b); 
            a = "efg"; 
            Console.WriteLine("a = {0}, b = {1}", a, b); 

输出结果是: 
a = abc, b = abc 
a = efg, b = abc 

显然b不是什么指向a的指针,而是一个新的string. 

string b = a; 
等价于 
string b; 
b = a; 

明白了吗?
--------------------编程问答--------------------
引用 46 楼 popnet 的回复:
绝对会的!
看代码:
string a = "abc";
string b = a;
Console.WriteLine("a = {0}, b = {1}", a, b);
a = "efg";
Console.WriteLine("a = {0}, b = {1}", a, b);

输出结果是:
a = abc, b = abc
a = efg, b = abc

显然b不是什么指向a的指针,而是一个新的string.

string b = a;
等价于
string b;
b = a;

明白了吗?


显然你没有理解C#中的“引用”是什么意思

string a = "abc";//创建一个string对象,暂称为s1,值为abc,a为指向s1的一个引用
string b = a;//将a的一个副本给b,也就是说a与b都是指向s1的不同引用
Console.WriteLine("a = {0}, b = {1}", a, b);
a = "efg";//此时再重新创建一个string对象,暂称为s2,值为efg,a不在指向s1,g改为指向s2,而b仍然指向s1
Console.WriteLine("a = {0}, b = {1}", a, b);
--------------------编程问答--------------------
引用 49 楼 popnet 的回复:
刚没看各位大虾的评论,写了个小程序,仔细一想,有问题。
直接比较b == a就知道,b和a是指向同一个内存地址的,但这里算不算new了一个string呢?
如果把语句 string b = a;
分解成 string b;  //这里算不算new了一个string????
b = a;
应该没问题吧。

引用 46 楼 popnet 的回复:
绝对会的!
看代码:
string a = "abc";
string b = a;
Console.WriteLine("a = {0}, b = {1}", a, b);
a = "efg";
Console.WriteLin…

你这里又说错了,string类型与别的引用类型不同,它是特殊的引用类型,因为==运算符比较的是string变量的值,而不是引用
string b;//这样b根本就是null,没有实例化,何来的new了一个string?
b=a;//是将a引用的一个副本给b,同样没有再new一个string --------------------编程问答--------------------
引用 50 楼 ojlovecd 的回复:
显然你没有理解C#中的“引用”是什…

的确,如果理解了“引用”就不会有这么多的意见了。 --------------------编程问答--------------------
引用 48 楼 ojlovecd 的回复:
b=a;是将a引用的一个副本传给b,也就是将a与b都指向同一个对象 

C# code
string b = "";//创建一个string对象,暂称为s1,值为空字符串,b指向这个s1
b = "123";  //再次创建一个string对象,暂称为s2,值为123,b不再指向s1,改为指向s2,如果s1再没有被其他变量引用,则GC会将它回收掉

string a = "123";//创建一个string对象,暂称为s1,值为123,a指向这个s1
string b = a;  //把a的一个副本赋值给b,b也指向s1,

st…


呵呵,string虽然是只读的,但也不是这样弄法的吧。。

string应该有字符串缓存池的,相同的初始化不会创建对象的。。。

string b = "";//创建一个string对象,暂称为s1,值为空字符串,b指向这个s1
b = "123";  //再次创建一个string对象,暂称为s2,值为123,b不再指向s1,改为指向s2,如果s1再没有被其他变量引用,则GC会将它回收掉

string a = "123";//不创建对象,指向S2

//喀,我不知道你这是不是连续的,SORRY

--------------------编程问答--------------------
引用 46 楼 popnet 的回复:
绝对会的! 
看代码: 
            string a = "abc"; 
            string b = a; 
            Console.WriteLine("a = {0}, b = {1}", a, b); 
            a = "efg"; 
            Console.WriteLine("a = {0}, b = {1}", a, b); 

输出结果是: 
a = abc, b = abc 
a = efg, b = abc 

显然b不是什么指向a的指针,而是一个新的string. 

string b = a; 
等价于 
string b; 
b = a; 

明白了吗?


我认为不会!你那么做是让a重新指向了另一个字符串“efg",而b仍然指向"abc"
string b; 不会创建新对象吧,只有用new才会创建新对象吧。刚开始接触C#,感觉这样写string b; b就相当于c++里的一个指针而已 --------------------编程问答-------------------- 哦... 学习了,谢谢!
引用 51 楼 ojlovecd 的回复:
引用 49 楼 popnet 的回复:
刚没看各位大虾的评论,写了个小程序,仔细一想,有问题。 
直接比较b == a就知道,b和a是指向同一个内存地址的,但这里算不算new了一个string呢? 
如果把语句 string b = a; 
分解成 string b;  //这里算不算new了一个string???? 
b = a; 
应该没问题吧。 

引用 46 楼 popnet 的回复: 
绝对会的! 
看代码: 
string a = "abc"; 
string b = a; 
Console.WriteLine("a = {0}, b = {1}"…
--------------------编程问答-------------------- 搞了半天 好像明白点点了..........

能不能把a给销毁然后再去看b的值了........

string a = "adfasdf";
string b = a;

a 销毁掉  (a能不能销毁、垃圾回收,销毁了应该就没得了吧)

MessageBox.Show(b);
--------------------编程问答--------------------
引用 3 楼 dancingbit 的回复:
我的回答是:不会


不会! --------------------编程问答--------------------
引用 56 楼 wxm3630478 的回复:
搞了半天 好像明白点点了.......... 

能不能把a给销毁然后再去看b的值了........ 
C# code

string a = "adfasdf";
string b = a;

a 销毁掉  (a能不能销毁、垃圾回收,销毁了应该就没得了吧)

MessageBox.Show(b);




using System;
using System.Collections.Generic;
using System.Text;

namespace string_test
{
    class Program
    {
        static void Main(string[] args)
        {
            string b;
            if (true)
            {
                string a = "abcd";
                b = a;
            }
            GC.Collect();
            Console.WriteLine(b);
        }
    }
}

结果是能够输出  abcd
--------------------编程问答-------------------- 我和你的结果一样  但有点迷糊

GC.Collect();//回收

那么b也回收了  怎么还有值了........难道没回收 --------------------编程问答--------------------
引用 59 楼 wxm3630478 的回复:
我和你的结果一样  但有点迷糊 

GC.Collect();//回收 

那么b也回收了  怎么还有值了........难道没回收

肯定没回收的,你得了解下回收机制。 --------------------编程问答-------------------- 学习下。。。引用类型和值类型。。。我支持不会
就像类的实例一样。。。。在内存中有就不会在次创建。。而是指向同一引用。 --------------------编程问答-------------------- 用Reflector看了下string的源代码,结果构造函数都让人很失望,看不出名堂,NND

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{
   static String()
{
    Empty = "";
    WhitespaceChars = new char[] { 
        '\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
        ' ', ' ', ' ', ' ', '​', '\u2028', '\u2029', ' ', ''
     };
}
[MethodImpl(MethodImplOptions.InternalCall), CLSCompliant(false)]
public extern unsafe String(char* value);
 
[MethodImpl(MethodImplOptions.InternalCall), CLSCompliant(false)]
public extern unsafe String(sbyte* value);
 [MethodImpl(MethodImplOptions.InternalCall)]
public extern String(char[] value);
[MethodImpl(MethodImplOptions.InternalCall)]
public extern String(char c, int count);
 


 

 

 

}
--------------------编程问答--------------------
引用 53 楼 ojekleen 的回复:
引用 48 楼 ojlovecd 的回复:
b=a;是将a引用的一个副本传给b,也就是将a与b都指向同一个对象

C# code
string b = "";//创建一个string对象,暂称为s1,值为空字符串,b指向这个s1
b = "123";  //再次创建一个string对象,暂称为s2,值为123,b不再指向s1,改为指向s2,如果s1再没有被其他变量引用,则GC会将它回收掉

string a = "123";//创建一个string对象,暂称为s1,值为123,a指向这个s1
string b = a;  //把a的一个副…


对,这也是string类的一个特点,如果已经在内存中存在某个值的string对象,那么再次声明一个具有此值的新string变量的时候,此变量将会直接指向那个string对象,不会重新创建,他那段代码我理解是三段不同的代码,不是写在一起的 --------------------编程问答--------------------
引用 60 楼 ojekleen 的回复:
引用 59 楼 wxm3630478 的回复:
我和你的结果一样  但有点迷糊

GC.Collect();//回收

那么b也回收了  怎么还有值了........难道没回收

肯定没回收的,你得了解下回收机制。

你该把你那个帖子的连接发给他看看 --------------------编程问答-------------------- 不会

只是把A的地址赋给B --------------------编程问答-------------------- . --------------------编程问答--------------------

会的
string和int一样都是值类型
string虽然说是引用类型,但是在C#中它和int一样
datatable,Array,ArrayList等才是真正的引用类型

如果是函数
string str;
public void test(ref str)
{
  
}

public void test(out str)
{
  
}
也就是,如果要引用改变了的string类型,必须得用ref或者out
而DataTable或者ArrayList就不用这样
DataTable dt = new DataTable();
public void test(dt)//注意这里不用ref或者out,所以这里是真正的引用类型
{
}

所以,会
--------------------编程问答-------------------- 先跟楼主说声sorry,在c#的帖子里面用c++来解释,不过我没学过c#,不懂c#里面的东西,所以就只能用c++的代码来解释了,我觉得c#和c++都是c的派生语言,在基本原理上应该是一样的。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a="asdfg";//暂时令a指向的对象为 对象①
string b=a;//b指向 对象①
string f=b;//a,b,f都是指向的同一个对象  对象①
string d="asdfg";//d指向的是新的地址空间,暂时令该string对象为 对象②
a[1]='m';//新生成一个string对象"amdfg" 对象③,a指向这个新的string对象
string h=a;//大家可能会以为h和a指向同一个string对象 对象③,错!a最开始指向 对象①,后来又
                      //指向了 对象③,由于这个原因h并不是指向对象③,而是新生成一个string对象,暂时另
                   //该对象为 对象④,对象④的内容是"amdfg"
string c=b;//c指向 对象①,因为b一直指向 对象① ,没变化过
d[1]='n';//由于d所指向的 对象② 只有d能够查找到,所以对该对象的更改并没生成新的string对象,而是直
                   //接改变该对象②的内容
a="aaaaa";//a任然指向 对象③,对象昂③ 的内容为"aaaaa",原因同上,因为目前只有a指向 对象③   
                  //只有a能查找到 对象③
d="ddddd";//d任然指向 对象②,只是对象②的内容变成了"ddddd"
b[1]='y';//新生成 对象⑤,对象⑤的内容是"aydfg",因为f也指向 对象①,所以b要指向新生成的对象⑤
string g=b;//g指向了新生成的string对象 对象⑥,对象内容是"aydfg",因为b开始指向 对象①,
                      //后来又指向对象 对象⑤。原理同string h=a;
b=a;//b任然指向 对象⑤,只是对象⑤的内容变为"aaaaa",因为只有b指向对象⑤,只能通过b找到对象⑤
return 0;
}

上面是我调试用的c++代码,没有任何的输入输出,关键是看程序运行过程中各个string变量所指的内存地址的变化(在先编译连接,然后在每一个语句前插入断点,然后单步运行,即调试运行,查看每个string变量指向的地址变化情况):
如果你有耐心的话会发现我总结的结论!


个人总结:如果一个string变量a始终指向同一个string对象(即之前a指向的地址没有变化过),则当有新定义的string变量b=a时,b和a指向同一个string对象,并不为b另外生成新的string对象。如果a并不是始终指向同一个string对(即指向的地址变化过),则当有新定义的string变量b=a时,b指向的是另外新生成的string的对象,只不过新生成的string对象的内容和a指向的对象的内容是一样的。

另外我想补充点:如果string变量a和b指向同一个对象①(即a和b指向同一个地址),任意通过a或者b改变对象①的内容是不可行的,因为有两个string变量同时指向对象①,例如运行:a="aaaaa",会另外新生成一个string对象②,对象②的内容是"aaaaa",a则指向新生成的对象②,而b任然指向对象①,对象①的内容也没用变化,如果继续运行:b="bbbbb",就不会另外新生成string对象了,而是直接将对象①的内容改变为"bbbbb",因为此时只有b指向对象①(即当某个string对象只有一个string变量指向时,可以通过该变量直接改变该对象的内容)。

所以楼主的问题:
string a = “adfasdf”;这个会重新new一个string对象, 
string b = a;b也会重新new一个string对象吗?
只看这两行代码:a是在string b = a前刚刚定义的,就是说一直指向对象"adfasdf"(即a指向的地址没变过),所以刚定义的string b = a不会重新new一个string对象!
至于在其他情况下是否一定会new新的string对象就要根据实际情况而定。


楼主,有耐心请看完,记得给分哦!
--------------------编程问答--------------------
引用 68 楼 whutsusan 的回复:
先跟楼主说声sorry,在c#的帖子里面用c++来解释,不过我没学过c#,不懂c#里面的东西,所以就只能用c++的代码来解释了,我觉得c#和c++都是c的派生语言,在基本原理上应该是一样的。 
#include <iostream> 
#include <string> 
using namespace std; 
int main() 

string a="asdfg";//暂时令a指向的对象为 对象① 
string b=a;//b指向 对象① 
string f=b;//a,b,f都是指向的同一个对象  对象① 
string d="asdfg";//d指…


虽然语言类似,但编译器是不一样的 --------------------编程问答-------------------- string 是一种特殊的引用类型 --------------------编程问答--------------------
引用 4 楼 yzy8788 的回复:
我感觉也不会,b应该只是指向a。 
不过不知道string类型的对象和其他对象有没有什么区别,要是没有区别的话,应该是这样的吧?

同意这个说法 --------------------编程问答-------------------- 加个精华吧,关于string的问题还是误导了很多人的。 --------------------编程问答-------------------- C#,string是一个特殊的引用类型,和int型类似
会,个人认为 --------------------编程问答-------------------- 这个和c++和C都不一样的 --------------------编程问答--------------------
引用 72 楼 ojlovecd 的回复:
加个精华吧,关于string的问题还是误导了很多人的。

其实加几个测试就应该知道了,只是很多人宁愿来这也不愿意去写代码

class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string a = "abc";
            string b = a;
            Console.WriteLine(string.ReferenceEquals(a,b));//true
            Console.WriteLine(string.Equals(a, b));//true

            string c = "abc";
            Console.WriteLine(string.ReferenceEquals(b, c));//true
            Console.WriteLine(string.Equals(b, c));//true

            string d = "a";
            string e = d+"bc";

            Console.WriteLine(string.ReferenceEquals(e, c));//false
            Console.WriteLine(string.ReferenceEquals(e, b));//false
            Console.WriteLine(string.Equals(e, c));//true
            Console.WriteLine(string.Equals(e, b));//true      

            Console.ReadLine();
        }
    }
--------------------编程问答--------------------
引用 74 楼 zhaoweiting0609 的回复:
这个和c++和C都不一样的

这个设计问题,别说是不同语言不相同了,就算是同一种语言不同版本也有可能不同的。 --------------------编程问答-------------------- 一个很好的学习机会啊 --------------------编程问答-------------------- 真是个学习的好地方啊 --------------------编程问答-------------------- string a = “adfasdf”;这个会重新new一个string对象, 
string b = a;b也会重新new一个string对象吗?


系统一开始分配了一个字符串常量,就是  "adfasdf"

然后,new了一个string类型的变量 a,这个变量(的值应该是一个指针)指向字符串常量 “adfasdf”

然后再new了一个strnig类型的变量 b,这个变量的值就是a的值(都是一个指针),也是和a一样,指向字符串常量 “adfasdf”;
--------------------编程问答--------------------
引用 79 楼 Linux7985 的回复:
string a = “adfasdf”;这个会重新new一个string对象, 
string b = a;b也会重新new一个string对象吗? 


系统一开始分配了一个字符串常量,就是  "adfasdf" 

然后,new了一个string类型的变量 a,这个变量(的值应该是一个指针)指向字符串常量 “adfasdf” 

然后再new了一个strnig类型的变量 b,这个变量的值就是a的值(都是一个指针),也是和a一样,指向字符串常量 “adfasdf”; 

变量是声明,不会new一个变量
声明变量不会有new的动作的,new是回去分配内存的 --------------------编程问答--------------------
一群唐僧
反正经常用的"字符串",前面加个@就是了。
String类型 在 C#里面是做过特殊处理的,和其他类型的处理方式不是很一样。 --------------------编程问答-------------------- 学习~! --------------------编程问答-------------------- 有没有什么工具可以调试看得到啊? --------------------编程问答-------------------- 不会! --------------------编程问答-------------------- b=a应该是指向同一个引用的
但如果a赋值的话,因为string是种特殊的引用类型,一旦修改或重新赋值就会指向一个新的地址,但对b却没影响 --------------------编程问答--------------------
引用 79 楼 Linux7985 的回复:
string a = “adfasdf”;这个会重新new一个string对象, 
string b = a;b也会重新new一个string对象吗? 


系统一开始分配了一个字符串常量,就是  "adfasdf" 

然后,new了一个string类型的变量 a,这个变量(的值应该是一个指针)指向字符串常量 “adfasdf” 

然后再new了一个strnig类型的变量 b,这个变量的值就是a的值(都是一个指针),也是和a一样,指向字符串常量 “adfasdf”; 

楼上的兄弟理解有点问题哈
两个表达式的处理方式应该是一致的,发生这种现象的原因主要是string类关于=重载实现的原因.在这里可以把其看作为一种特殊的引用类型。 --------------------编程问答-------------------- 好贴 --------------------编程问答-------------------- 其实加几个测试就应该知道了,只是很多人宁愿来这也不愿意去写代码 

C# code
class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string a = "abc";
            string b = a;
            Console.WriteLine(string.ReferenceEquals(a,b));//true
            Console…
[/Quote]

这个已经给出了最好的回答 --------------------编程问答-------------------- 会的,a赋值给b是重新在内存中开辟了一块区域,a和b引用的是不同的内存地址,这个书上就有,而且你也可以自己试试,string b=a后,改变b的值,a的值是不变的。 --------------------编程问答-------------------- 不会的,只是指向那块内存地址
--------------------编程问答--------------------
引用 38 楼 ojlovecd 的回复:
想知道会不会,试一下就知道了 

C# code
            string a = "ojlovecd";
            string b = a;
            Console.WriteLine(a == b);
            Console.WriteLine((object)a == (object)b);




输出当然是True True了 
虽然string是比较特殊的引用类型,但归根结底还是引用类型,string b = a;只是把a的引用给了b,也就是它们都指向同一块内存空间。 
MSDN中讲String 对象称为不可变的(只读),…

  m --------------------编程问答--------------------
引用 9 楼 ralpha08 的回复:
不会, .net用散列表保存字符串,当新创建一个字符串的时候,会去散列表中检测这个字符串是不是存在,如果存在返回已经存在的内存地址中的字符串,这样做显然不会创建一个新的字符串 

但是如果这样 

string a = “adfasdf”;这个会重新new一个string对象, 
string b ="adf"; 
b+="asdf"; 

这时候 string.ReferenceEquals(a, b) 返回false; 
因为b创建了两个字符串 "adf"和"asdf" 

不会,并没有分配内存地址,只是定义一个变量,变量指向a --------------------编程问答-------------------- java中当然不会了,c#就不了解了 --------------------编程问答-------------------- string a=。。。
因为string是引用类型所以会在栈上分配一个引用指向堆上的创建new的对象
而string b=a只是a的一个副本,没有在堆上分配对象,也就不存在new了 --------------------编程问答--------------------
引用 89 楼 Profiteerchen 的回复:
会的,a赋值给b是重新在内存中开辟了一块区域,a和b引用的是不同的内存地址,这个书上就有,而且你也可以自己试试,string b=a后,改变b的值,a的值是不变的。

改变b的值与改变b引用的string的值,可是两码事... --------------------编程问答-------------------- C#中 string 类型的变量一旦对字符串对象进行初始化,该字符串对象就不能改变,修改字符串内容实际上是创建一个新的字符串。,会的,a赋值给b是重新在内存中开辟了一块区域,a和b引用的是不同的内存地址,这个书上就有,而且你也可以自己试试,string b=a后,改变b的值,a的值是不变的。string 类型的数据每变动一次就会分配一个新的内存存储该数据,而以前的内存依然存在。


结果是肯定会的 --------------------编程问答--------------------
引用 96 楼 qgylovelj 的回复:
C#中 string 类型的变量一旦对字符串对象进行初始化,该字符串对象就不能改变,修改字符串内容实际上是创建一个新的字符串。,会的,a赋值给b是重新在内存中开辟了一块区域,a和b引用的是不同的内存地址,这个书上就有,而且你也可以自己试试,string b=a后,改变b的值,a的值是不变的。string 类型的数据每变动一次就会分配一个新的内存存储该数据,而以前的内存依然存在。 


结果是肯定会的

同意楼上的,string如果赋值就会分配内存。
为什么.net有个stringBuilder类呢,就是这个原因。如果是stringBuilder类型的如果改变他的值,那么他就直接改变内存对象。
string 只要改变一次,就会新建一个内存区域。 你在网上搜一个string和stringbuilder 就明白了。 --------------------编程问答-------------------- new 出来的,当然就是一个新对象咯~ --------------------编程问答-------------------- 会的。string就是一个特殊的引用类型! --------------------编程问答--------------------
引用 89 楼 Profiteerchen 的回复:
会的,a赋值给b是重新在内存中开辟了一块区域,a和b引用的是不同的内存地址,这个书上就有,而且你也可以自己试试,string b=a后,改变b的值,a的值是不变的。


这个不能成为理由,当你改变b的值,是如何改变呢?
如果是
 b = "ddee";
这个相当于 b = new String("ddee");当然是创建了一个新的对象。

b = c;
虽然string是一种特殊类型,但它还是引用类型,它还是存在堆里的,而b仅仅是一个变量而已,这样的赋值只是让b变量指向了c指向的堆里的内存块而已。而b原先指向的内存块还是存在的,如果它没有被其他string变量引用,那么到时候会被回收掉。

记得之前看过一篇博客,是这样的
string a = "abc";
string b = "abc";
它说这样b也不会去创建新的对象,而只是指向了a指向的堆里的有"abc"的内存块。

这个说法和我上面说的原理是一样的,至于说当把string传递到一个方法体,在方法体里更改传递参数后,string 的值没有发生变化,这个我认为编译器做了处理,因为string是一个基础类型,要遵循基础类型的一些处理规范。

最后从性能上的一个考虑上来说,如果string的变量之间的赋值会导致重新new对象的话,那v.netframework的性能就会太低,如果代码里的有10个几百个字符的字符串变量,哪怕每个做那么1到2次赋值语句,你可以想象如果这个代码调用很频繁的话,那会是什么结果呢?(这种情况是框架无法控制的,谁能保证不会有这种情况出现呢?)
这样也能理解struct赋值是重新copy的理由,因为struct不会很大,基础类型里最大的decimal,也只有16个字节,是可控的。

当然这里又引申出另外一个问题了,自定义struct里有很多属性都是int或者double型的,当这个类型的变量赋值的时候是否会全部都copy一遍呢?如果是,这就是我们在考虑设计一个对象的时候从性能的角度去考虑的一个问题了,对于这种情况的对象定义,最好定义为class 而不要定义为struct。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,