欲证明 C# 中引用类型,改变两个相等的引用类型,则另一个也随之改变。结果发现class 可以,但string不行。为什么?Employee ee1 = new Employee();
Employee ee2 = ee1;
现在,因为类在 C# 中为引用类型,所以 ee1 被视为对 Employee 的引用。在前面的两行中,第一行在内存中创建 Employee 的一个实例,并设置 ee1 以引用该实例。因此,将 ee2 设置为等于 ee1 时,它包含了对内存中的类的重复引用。如果现在更改 ee2 上的属性,则 ee1 上的属性将反映这些更改,因为两者都指向内存中的相同对象,如下所示:
原文:http://msdn2.microsoft.com/zh-cn/library/ms228360(vs.80).aspx小实验如下:
Default2.aspx.cs代码
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;public partial class Default2 : System.Web.UI.Page
{
    class class1
    {
        public int vau = 000;
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        string str1 = "str1 ";
        String str2=str1;
        str2 = "str1 xxx";        Label1.Text = str1;
        Label2.Text = str2;
         int i = 10;
        int k = i;
        i = 20;
        Label3.Text = i.ToString();
        Label4.Text = k.ToString();        class1 a =new class1();
        class1 b = a;
        b.vau = 123;
        Label5.Text = a.vau.ToString();
        Label6.Text = b.vau.ToString();        
    }
}
Default2.aspx的代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>无标题页</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="Label1" runat="server" Width="149px"></asp:Label>
        <br />
        <br />
        <asp:Label ID="Label2" runat="server" Width="149px"></asp:Label>
        <br />
        <br />
        <br />
        <asp:Label ID="Label3" runat="server" Width="147px"></asp:Label>
        <br />
        <br />
        <asp:Label ID="Label4" runat="server" Width="147px"></asp:Label>
        <br />
        <br />
        <br />
        <asp:Label ID="Label5" runat="server" Width="145px"></asp:Label><br />
        <br />
        <asp:Label ID="Label6" runat="server" Width="141px"></asp:Label></div>
    </form>
</body>
</html>

解决方案 »

  1.   

    运行后发现只有string类型的label值没有随之改变,为什么?
      

  2.   

    str2 = "str1 xxx";
    b.vau = 123;
    比较一下区别在哪。
      

  3.   

    str2 = "str1 xxx";
    b.vau = 123;
    比较一下区别在哪
    ==========================
    说吧,我菜鸟
      

  4.   

    string 在怎么说也是引用类型吧。
      

  5.   

    vau是类的成员属性啊, str2 = str1,str2 = "str1 xxx"; "str1 xxx"其实也是当做一个引用类型,str2的引用都变了,当然输出就和Str1不同了。 str1 和 “str1 xxx”是等价的
      

  6.   

    那我怎么改,才能把string “引用类型改一个另一个也随之改变”体现出来
      

  7.   

    string 是不可变的对象,你给它重新赋值的时候它已经不是原来的那个呀
    要实现上面的效果要用stringbuilder 对象
      

  8.   

    string经过了特殊处理,每次改变值时都会建立一个新的string对象,变量会指向这个新的对象,而原来的还是指向原来的对象,所以不会改变。这也是string效率低下的原因,如果经常改变string的值则应该使用StringBuilder而不使用string
      

  9.   

    "="号对于string已经不是普通的引用赋值的意义了应该是重载了=号操作符,具体没研究过一看见=号,就应该是实例化另一个string对象,里面的值是一样的,但引用地址不同了
      

  10.   

    StringBuilder 类  表示可变字符字符串。
      

  11.   

    看来string 还是接近值类型
    stringbuilder需要引用using System.Text;
      

  12.   

    string 是特殊的引用类型...尽管 string 是引用类型,但定义相等运算符(== 和 !=)是为了比较 string 对象(而不是引用)的值。这样做是为了使对字符串相等性的测试更为直观。string 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 string 对象的方法实际上是返回一个包含修改内容的新 string 对象。如果需要修改字符串对象的实际内容,请使用 System.Text.StringBuilder 类。
      

  13.   

    http://blog.csdn.net/GnuDoyng/archive/2005/01/24/266647.aspx
      

  14.   

    StringBuilder s =  new StringBuilder();
            s.Append = "sdsds";
            StringBuilder x = s;
            x.Append = "123123";        Label7.Text = s.ToString();
            Label8.Text = s.ToString();还是不对啊
      

  15.   

    StringBuilder strbuild = new StringBuilder();
                strbuild.Append("fdalsf;lsdf");
                StringBuilder b = strbuild;
                b.Append("lily");
                
                Console.WriteLine(strbuild);
                Console.WriteLine(b);
      

  16.   

    我记忆中在C#中String类型不是引用类型,而是值类型,每次像str1=str2或者void function( string str)这样的情况都会发生拷贝,会重新开辟出一块内存。因此,在有大的string的处理的时候就开销就很大了,反复的擦写十分降低效率。为了解决这个问题,于是有了StringBuider这个类,他是引用类型的,如果不用Copy的话,就会出现你上面讲的那个问题,特别是向函数传参数的时候尤其注意,也许你一个不小心就把整个结果搞乱了。不过StringBuilder十分节约,如果在一个函数内部进行字符串处理的时候,还是选用StringBuilder为好,传参就用String吧。
      

  17.   

    StringBuilder strbuild = new StringBuilder();
                strbuild.Append("fdalsf;lsdf");
                StringBuilder b = strbuild;
               ///----------------------
                b.Remove(0, b.Length);
                b.Append("lily");
                //--------------------------
                Console.WriteLine(strbuild);
                Console.WriteLine(b);
      

  18.   

    其实每次你修改string类型的值都重新发生一次内存的分配,所以不存在引用例如
    string str;
    str = "1"; 分配内存
    str = "2"; 擦除内存,重新分配
      

  19.   

    string就是一个不可以修改内容的引用类型,并没有什么特殊性。
    str2 = "str1 xxx";是对str2的重新赋值,而b.vau = 123;是对b的vau属性赋值。
      

  20.   

    to li45214521(快毕业了,要找工作了)  年轻有为啊,呵呵。
    to pikapi() 
    非常感谢二位的回帖!乐于助人,积德啊。
      

  21.   

    b.Remove(0, b.Length);
    应该是从零的位置获取其长度,就是将其清空吧。
      

  22.   

    晕倒,你们的回答都会误导别人的。
    看看这个吧  http://www.cnblogs.com/3echo/archive/2006/02/13/329484.html
      

  23.   

    给string赋值的时候会开辟新的内存空间,所以lz要的效果只能用StringBuilder来实现,StringBuilder对象的特点是:重新赋值时不会开辟新的内存空间,而是在当前的内存空间后面续加,不会再另外开辟!