之前知道,值类型作为方法参数的时候,方法会创建值类型的副本,在方法内改变值,不会影响方法外的变量,除非返回改变值,或用ref,out关键字。
但引用类型在工作中写方法的时候一般也是默认用值类型的方式写。
比如有个Person类。
1 public class Person{ 2 public string Name; 3 public int Age; 4 public override string ToString(){ 5 return string.Format(" Name = {0} , Age = {1}",this.Name,this.Age); 6 } 7 }
要改变里面的内容,原来都是这样写
1 public Person OldChange(Person p){ 2 p.Name = "newChange"; 3 p.Age = "123"; 4 return p; 5 }
然后在主函数的时候会写成这样
1 void Main() 2 { 3 Person p = new Person(); 4 p = OldChange(p); 5 Console.WriteLine(p.ToString()); 6 }
运行结果
1 Name = newChange , Age = 123
看起来没什么问题,可真的要有返回值吗,引用类型不本身就是引用吗,直接改就完了。
试试下面的方法
1 public void Change(Person p ){ 2 p.Name = "Change Without Return"; 3 p.Age = 5; 4 }
调用的时候就不要赋值了直接显示
1 void Main() 2 { 3 Person p = new Person(); 4 Change(p); 5 Console.WriteLine(p.ToString()); 6 }
运行结果
1 Name = Change Without Return , Age = 5
同样没什么问题,看来可以省一步赋值了
如果真的可以直接在方法里改变引用类型的值,那么重新赋值给这个引用,值会不会改呢。
写个新方法
1 public void SetNewPerson(Person p ){ 2 p = new Person(); 3 p.Name = "created by method"; 4 p.Age = 99; 5 }
在方法里直接写个新的实例化类,并将参数指像这个新的实例,主程序同上一个差不多
1 void Main() 2 { 3 Person p = new Person(); 4 SetNewPerson(p); 5 Console.WriteLine(p.ToString()); 6 }
运行结果
1 Name = , Age = 0
看来,并没有传递到。
也就是说,方法在引用类型上,复制的是引用类型的引用,方法参数和函数外的变量同时指像一个对象。
方法中改变的是复制后的引用,方法外部并没有改变指像,所以会产生这种状况。