class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person("ddd", 10);
            p.Display();//输出ddd,10
            Send(p);
            p.Display();//输出xxx,99
            string a = "111111";
            Console.WriteLine(a);//输出111111
            Send(a);
            Console.WriteLine(a);//输出111111,为什么不是22222
            Console.ReadKey();
        }        static void Send(string s)
        {
            s = "222222";
        }
        //复制的是对象的引用,同一对象
        static void Send(Person p)
        {
            p.Age = 99;
            p.Name = "xxx";
        }    }
    class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public Person(string n, int a)
        {
            Age = a;
            Name = n;
        }
        public void Display()
        {
            Console.WriteLine("Name:{0},Age:{1}",Name,Age);
        }
    }求输出解决的原因?

解决方案 »

  1.   

            static void Send(string s)
            {
                s = "222222";
            }=>        static void Send(ref string s)
            {
                s = "222222";
            }
      

  2.   

    Send(a);
    =>
    Send(ref a);
      

  3.   

     static void Send(ref string s)好朋友=女子月月友
      

  4.   

    试试这个string a = "a";            
    string b = a;Console.WriteLine(object.ReferenceEquals(a, b));//true——说明引用相同a = "aaa";Console.WriteLine(object.ReferenceEquals(a, b));//false——说明引用不同想想为什么在改变a的值前后,为什么改变了a的引用
      

  5.   

    也就是说当为a赋值的时候,其实是为a重新创建了一个对象(因为引用被改变了),所以static void Send(string s)
    {
           s = "222222";
    }这里面的a是一个新的对象,和外面的变量a是两码事,当然改变s的值不会影响外面的a的值啦!!
      

  6.   

    换句话说,如果你将
    static void Send(Person p)
    {
        p.Age = 99;
        p.Name = "xxx";
    }
    改为
    static void Send(Person p)
    {
        p = new Person("xxx", 99);    p.Age = 99;
        p.Name = "xxx";
    }那么,打印出来的值还是不会变的试试吧!!
      

  7.   

    给你个链接,仔细理解其中设计的几种场景,对你理解C#的参数传递非常有帮助。
    http://www.cnblogs.com/DonLiang/archive/2008/02/16/1070717.htmlstring a = "111111";
    Console.WriteLine(a);//输出111111
    Send(a);
    Console.WriteLine(a);//输出111111,为什么不是22222static void Send(string s)
    {
         s = "222222";
    }
    你的上述代码里,把Send(string)函数内部的s="222222"理解成s = new string ("22222"), 再比照上面链接里的情形,你就清楚了。
            
      

  8.   

    Lz加油,然后我提个建议
    如果有空上网查下形参ref和out的使用,以上问题自然就能解决了,
    哎,用手机打这么几个字都累
      

  9.   

    static void Send(string s)
      {
      s = "222222";
      }=>  static void Send(ref string s)
      {
      s = "222222";
      }
      

  10.   

    string的特殊之处在于:传递string参数时,传递的是引用(传址),但方法中不可以修改它,这是因为string设计上不能修改的,修改就会产生一个新的string,所以在用代码作测试时,string会看起来像一个传值的调用(在方法中修改不影响原先的变量)
      

  11.   

    string是特殊的引用类型。在进入send方法修改之前,引用的都是同一块内存,当在方法内对str修改后,会对该str重新分配一块内存。 
    如果想按引用传递的话可以通过ref
      

  12.   

    记住是这样就好了,实在想问为什么,随便找本讲c#语言的,就有详细的讲解
    PS:所谓讲解其实也是建立在说服上面,没有真理,定理让你来推论
      

  13.   

    解决问题的方法多了去了,关键是Why。
      

  14.   

    不是说当对str修改后会重新分配?既然重新分配了怎么还会是引用同一地址?
    至于微软为什么这样做,你可以去问他们clr小组!
      

  15.   


    还不明白??
    我12喽回答的你看了没??在这个方法里面
            static void Send(string s)
            {
                s = "222222";
            }
    p是一个局部变量,当为它赋值的时候,就是重新构造对象了,22L和23L的朋友说明了这个问题。。那么你再看一下我12L的回复和下面的对比一下就明白了
    static void Send(Person p)
    {
      p = new Person("xxx", 99);//主要是这儿,重新构造对象。在另一个Send方法里面,为string str赋值和这儿是一样的意思。  p.Age = 99;
      p.Name = "xxx";
    }
      

  16.   

    这就是为什么又好多拼接字符串的时侯尽量用StringBuilder对象了至于为什么string类型要设置成这样,只能说随着你工作经验慢慢会体会到更多。至于设计c#语言的大师是怎么想的,你只有去看一下比较权威的资料了
      

  17.   


    首先,声明的值为“11111”的a和方法Send中形参a,不是同一个a,Send中也可以叫做b;
    第二,传引用的意思是,把内存地址的引用传给了形参;传地址的意思是,把内存中的值传给了形参,(但是开辟了一个新的内存保存了这个值);所以方法中,传引用修改的是原内存中的值,传值只是修改了新内存中的值;
    第三,方法体结束以后,方法外的那个a,引用的还是原内存的地址,输出的也是原内存的值;而方法内的那个既可以是a也可以是b的那个形参,改变了不会对a有任何影响。注意:如果是传引用,方法内就是对于原内存的值进行了修改,就像Send(Person p)那样。
      

  18.   

    string 有些树上把它称为 不可变的引用类型,它虽然是引用类型,在堆上分配内存,但是他是不可变的,任何引用只是引用它的一个副本而不是它本身,在这一点上他和值类型是一样的。
      

  19.   

    支持!
    这其实是值类型与引用类型赋值上的区别,string实际上是引用类型,只不过它的发现像值类型,大概是MS重写了string类的=操作符.也就是说当你给一个string变量赋值时实际等于new了一个新对象,把那个string变量指向这个新对象,所以说它赋值的表现像值类型.
      

  20.   

    每次都这样,真是无法忍受了...这问题跟string类型P关系都没有!去看一篇老文...【.NET版月经问题】之二【引用类型参数就是按引用传递吗?】
      

  21.   

    再举个例子,你把Send(Person p)修改成如下这种形式,p.Display()输出的应该还是输出ddd,10
    也是因为方法内,重新开辟了内存保存了new Persion("xxx",99),而不是修改了原内存中的值。static void Send(Person p)
    {
         p = new Persion("xxx",99);
    }
      

  22.   

    其实你看一下我10L的回答就可以明白
    static void Send(string s)
    {
         s = "222222";
    }
    上面这个方法了
    关键是当你为局部变量s赋值的时候,这个时候s已经被重新构造了。所以和外面的变量不是一个引用,所以你改变这个里面的值和外面的没有关系再看一遍这个:string a = "a";  
    string b = a;Console.WriteLine(object.ReferenceEquals(a, b));//true——说明引用相同a = "aaa";Console.WriteLine(object.ReferenceEquals(a, b));//false——说明引用不同想想为什么在改变a的值前后,为什么改变了a的引用
      

  23.   

    只有讲不好,没有理解不了!
    //第一组
    string a = "a";
    string b = a;Console.WriteLine(object.ReferenceEquals(a, b));//true——说明引用相同a = "aaa";Console.WriteLine(object.ReferenceEquals(a, b));//false——说明引用不同//第二组
    Person p = new Person("ddd", 10);
    Person p2 = p;Console.WriteLine(object.ReferenceEquals(p, p2));//true——说明引用相同p = new Person("aaa",22);Console.WriteLine(object.ReferenceEquals(p, p2));//false——说明引用不同
      

  24.   

    说简单点,string 是引用类型,但在用的时候,你可以把它当做值类型来看。
    注意:只是用的时候这么看。
      

  25.   

    楼主还没想明白???要面壁思过啊,我感觉我讲的很清楚了想想我45L的回答,为什么a = "aaa";p = new Person("aaa",22);这两句代码达到的效果是一样的(都改变了原来的引用)???
      

  26.   

    引用类型是通过引用来访问对象,但对于对象引用本身而言如没用不ref modifier 的话本质仍是按值传递,从而
    使形参和实参具有相同的对象引用,从而使形参和实参指向同一对象,在这个例子中send(string)使形参分配一个新的对象引用“222222“从而使形参指向一个新的string,但这不影响实参的对象引用,也就是说实参仍指向原对象,所以输出的值不会因send(string)而改变,对于send(person)只是对所指对象的成员进行赋值,并没有分配一个新的对象引用,所以形参和实参指向同一对象,对形参所指对象的任何改变反映到实参所指对象。所以send(person)后实参所指对象的成员改变。
      

  27.   


    这个确实。 不是string,换个引用类型,也是一个道理。
      

  28.   

    这才是正解,string类型是个特殊的引用类型!