none
C#关于方法的参数 RRS feed

  • 问题

  • class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Person();
                p1.Age = 10;
                p1.Name = "Jim";
                Console.WriteLine(p1.Age+p1.Name);
                change(p1);
                Console.WriteLine(p1.Age + p1.Name);
                string s1 = "ssssssssssss";
                Console.WriteLine(s1);
                changestring(s1);
                Console.WriteLine(s1);
                Console.ReadKey();
            }
            static void change(Person p)
            {
                p.Age = 999;
                p.Name = "bill gates"; 
            }
            static void changestring(string s)
            {
                s = "fuck you";
            }
        }
        class Person
        {
            public int Age { get; set; }
            public string Name { set; get; }
        }
    -------------------输出结果-----------------
    10Jim
    999bill gates
    ssssssssssss
    ssssssssssss



    我自己定义了一个Person类,两个方法
    我的问题是:关于方法参数(两个方法的参数都是值传递,没有加ref和out ,但是change()方法能改变Person 变量,当changestring()方法不能改变string变量,这是为什么呢 
    2013年1月17日 15:28

答案

  • static void change(Person p)
            {
                p.Age = 999;
                p.Name = "bill gates"; 
            }
            static void changestring(string s)
            {
                s = "fuck you";
            }

    chang(Person p) 传入的参数是类,引用类型,成员变量赋值会被修改;

    changestring(string s)是值传递,如果是changestring(s1); 相当于s1复制一份在函数changestring内运算,出了方法体{}就结束了,s1还是原来的s1. 加上ref ,changestring(ref s1); 就相当于引用型使用了。

    2013年1月18日 6:31
  • 楼主,请先删除以下代码,或者更改成输出其它的测试语句:

     static void changestring(string s)
            {
                s = "我的测试字符串";
            }

    回到你的问题:

    准确而言,这个问题并不是“字符串可变不可变”的问题,孟版主的结论这里有些值得商榷(而是说在调用change函数的时候把string传入,函数的“s”形成了一个函数体级别的私有变量。s也指向字符串;然后你再函数体内把s重新赋值,意味着函数体内部的s发生了指向性的改变。但是出了函数体之后s自动被回收。自然原来的字符串没有改变。

    进一步证明此类现象:

    class Program
        {
            static void Test(object obj)
            {
                obj = null;
            }
            static void Main(string[] args)
            {
                object o = new object();
                Test(o);
                //你说o的结果会是null吗?
            }
          
        }

    证明一个问题:如果函数体内临时引用变量和调用部分的引用变量同时指向一个地方,那么一个改变另一个也一定改变;如果函数体内临时引用变量自身指向发生变化,那么不会影响到外部引用变量的实体(此时就需要引用ref了)。所谓“绝对引用”和“相对引用”问题。


    帮助一起改进论坛质量?提交你的意见于此。
    我的博客园
    慈善点击,点击此处
    和谐拯救危机,全集下载,净化人心

    2013年1月18日 6:34
    版主

全部回复

  • Person 是对象引用类型,

    String虽然也是引用类型,但字符串对象是不可变的:即它们创建之后就无法更改。

    http://msdn.microsoft.com/zh-cn/library/vstudio/ms228362.aspx


    【孟子E章】



    2013年1月18日 5:24
    版主
  • 你把 Change 方法改一下,你可能会更好的理解这个问题,如下:

     static void change(Person p)
            {
                p = new Person
                {
                    Age = 999,
                    Name = "bill gates"
                };
            }


    知识改变命运,奋斗成就人生!

    2013年1月18日 6:13
    版主
  • static void change(Person p)
            {
                p.Age = 999;
                p.Name = "bill gates"; 
            }
            static void changestring(string s)
            {
                s = "fuck you";
            }

    chang(Person p) 传入的参数是类,引用类型,成员变量赋值会被修改;

    changestring(string s)是值传递,如果是changestring(s1); 相当于s1复制一份在函数changestring内运算,出了方法体{}就结束了,s1还是原来的s1. 加上ref ,changestring(ref s1); 就相当于引用型使用了。

    2013年1月18日 6:31
  • 楼主,请先删除以下代码,或者更改成输出其它的测试语句:

     static void changestring(string s)
            {
                s = "我的测试字符串";
            }

    回到你的问题:

    准确而言,这个问题并不是“字符串可变不可变”的问题,孟版主的结论这里有些值得商榷(而是说在调用change函数的时候把string传入,函数的“s”形成了一个函数体级别的私有变量。s也指向字符串;然后你再函数体内把s重新赋值,意味着函数体内部的s发生了指向性的改变。但是出了函数体之后s自动被回收。自然原来的字符串没有改变。

    进一步证明此类现象:

    class Program
        {
            static void Test(object obj)
            {
                obj = null;
            }
            static void Main(string[] args)
            {
                object o = new object();
                Test(o);
                //你说o的结果会是null吗?
            }
          
        }

    证明一个问题:如果函数体内临时引用变量和调用部分的引用变量同时指向一个地方,那么一个改变另一个也一定改变;如果函数体内临时引用变量自身指向发生变化,那么不会影响到外部引用变量的实体(此时就需要引用ref了)。所谓“绝对引用”和“相对引用”问题。


    帮助一起改进论坛质量?提交你的意见于此。
    我的博客园
    慈善点击,点击此处
    和谐拯救危机,全集下载,净化人心

    2013年1月18日 6:34
    版主