就是这两句:s = new Student("li4");
            //s.Name = "li4";
s = new Student("li4");的话就输出zhang3s.Name = "li4";的话就输出li4why????class Student
    {
        private string name;        public string Name
        {
            get { return name; }
            set { name = value; }
        }        public Student(string _name)
        {
            name = _name;
        }
        static void Main()//Main_4_3_4
        {
            Student s = new Student("zhang3");
            ChageName(s);
            Console.WriteLine(s.Name);
            Console.Read();
        }        static void ChageName( Student s)
        {
            s = new Student("li4");
            //s.Name = "li4";
        }
    }

解决方案 »

  1.   

            static void ChageName( Student s)
            {
                s = new Student("li4");  // 生成新的副本,不会传递回调用的函数。
                //s.Name = "li4";        // 没有生成新的实例,对传递进来的s赋值。
            }
      

  2.   

           static void Main()//Main_4_3_4
            {
                Student s = new Student("zhang3");
                ChageName(ref s);
                Console.WriteLine(s.Name);
                Console.Read();
            }        // 加上ref,就会改变传递进来的s。
            static void ChageName(ref Student s)
            {
                s = new Student("li4");
            }
      

  3.   

    按照我贴的代码来说:这是引用类型的按值传递吧?
    引用类型的按值传递不应该改变s实例啊......
    也就是说
            s = new Student("li4");
           s.Name = "li4";
    两句都应该不改变s啊....
    why not?
      

  4.   

    static void ChageName( Student s)
            {
                s = new Student("li4");
             }这时:是把原本指向zhang3的s指向了li4而下面:
    static void ChageName( Student s)
            {
              s.Name = "li4";
            }这个型参s和实参s是指向同一个zhang3,而这样一操作就变成了li4
    请大家看一下解释的对不对
    对的话就结贴了
      

  5.   

    这时:是把原本指向zhang3的s指向了li4 
    ------
    不对...new Student("li4")产生新的实例...它和你“原本指向zhang3的s”没有任何关系...3、4楼解释的很清楚了...
      

  6.   

    还是引用的问题
    3楼说得没错,你把Main方法的 Console.WriteLine(s.Name)语句放到 ChageName方法里再跑一遍看看区别就知道了
      

  7.   

    原本指向zhang3的s我说的这个s是static void ChageName( Student s)里面的参数s......
      

  8.   

    static void ChageName( Student s)
            {
                s = new Student("li4");
             }型参和实参原本都指向zhang3,运行s = new Student("li4");之后型参指向了li4,而实参仍然指向zhang3而下面: 
    static void ChageName( Student s)
            {
              s.Name = "li4";
            }这个型参s和实参s是指向同一个zhang3,而这样一操作,实例的Name属性就从zhang3变成了li4 
    请大家看一下解释的对不对 
    我觉得这样解释似乎是和3、4L一致的
    [/Quote]
      

  9.   

    这实在是一个奇怪的问题,不知道是不是C#的BUG!!同样的情况,我在VC++2008下试了一下,显示的都是zhang3,因为static void ChageName( Student s)传递参数定义的是传值,所以S在函数中怎么改变,应该回来后恢复原值,C++中是比较符合传值的本意的,在C#中确实出现楼主的问题!!!!!!所以以后用C#编程要小心喽!!!!!!!!
      

  10.   

        static void ChageName( Student s)
            {
                s = new Student("li4");  // 生成新的副本,不会传递回调用的函数。
                //s.Name = "li4";        // 没有生成新的实例,对传递进来的s赋值。
            }这个是正确的
      

  11.   

    路过接分~By the way:以后尽量避免出现这种逻辑问题。
      

  12.   


    class Student
        {
            private string name;        public string Name
            {
                get { return name; }
                set { name = value; }
            }        public Student(string _name)
            {
                name = _name;
            }
            static void Main()//Main_4_3_4
            {
                Student s = new Student("zhang3");
                ChageName(out s);
                Console.WriteLine(s.Name);
                Console.Read();
            }        static void ChageName(out Student s)
            {
                s = new Student("li4");
                //s.Name = "li4";
            }
        }参数加上out关键字就行
      

  13.   

    谢谢16L
    我知道ref或者out是按引用传参
    我主要是问一下12楼的解释对不对啊...
      

  14.   

    就是12楼的解释,这个是典型的值传递和引用传递问题啊!
    你传进来的是一个引用(类似于c++地址),你只能改变这个引用的对象的值,不能改变这个引用本身。
    所以:s=new() 新new的是传不出去的。
      

  15.   

    static void ChageName( Student s)
            {
                s = new Student("li4");
                //s.Name = "li4";
            }
    中的s对象的作用域(生命周期)仅限此方法中
    原主函数中的不是同一个s.可能这么理解它们之间没关系的.
      

  16.   


            static void ChageName(Student s)   //形参是在栈上的实参的拷贝,和实参指向的是堆上的同一块区域。
            {
                s = new Student("li4");        //形参声明对象,形参指向新的地址,而是参没有变化
                //s.Name = "li4";              //形参的Name变化,因为形参和实参指向的是堆上的同一块区域,所以形参的Name变化,同时实参的Name也变化
            }所以会出现楼主的结果。可以用ref / out进行强制引用
      

  17.   

    补充一下, 因为 s = new Student("li4"); 
    所以s对象是个副本,对它的修改不会影响到Main()中的s变化的.如果想变化就用ref关键字把s作引用参数传递.
      

  18.   

    我明白了,这不是C#的Bug,只是C#和C++中的概念不是一样的!对于C#来说,当参数前不加ref或out是按值传递的,但对于参数是值类型和参数是引用类型的参数其表现是不一样的。对于引用类型,对于引用本身是按值传递的(不加ref时),所以s = new Student("li4"); 不会影响Main()函数中引用s指向的内存位置,所以返回时Main()函数中引用s所指向的内容是不会改变的,但当“s.Name = "li4";”时,由于Main()函数中引用s和ChageName函数中的S指向的是同一个内存位置,所以实际上把Main()函数引用s指向的内容改变了!!!当加上ref或out后“引用参数”本身是按引用(地址)传入的,这时Main()函数和ChageName函数中的S似乎就是一个东西(也许实际上ChageName函数内的s是Main()函数中s引用的引用)。在C++中ChageName(Student s),就是整个对象的传值, C++中会把Student 对象通过拷贝构造函数复制一份,所以从表面看和C#的表现不一样的,所以从C++转到C#的程序员,在这里可要注意了!以上是我的理解,也许有不对的地方下面是Effective C#中对“值类型和引用类型”的描述:
    http://dev.yesky.com/msdn/47/3494047.shtml
      

  19.   

    按值传递引用类型,顾名思义,s的值传入ChangName()方法了,而s的引用却没有。                         因此改动s=new Student("li4")想把s重新定向是痴人做梦,s的引用根本没传进来,怎么重定向?而s的值传入ChangName()方法了,所以改动s.Name="li4";是有效的。