标签:
把数据传入方法中,可以使方法有多个返回值。
值参数,通过将实参的值复制到形参的方式传递数据。值参数的实参可以是变量或者是表达式
下面是一个简单的值参数传递的过程
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 SomeData v1 = new SomeData(); 6 int v2 = 30; 7 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 8 Calculate(v1, v2); 9 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 10 11 } 12 13 static void Calculate(SomeData p1, int p2) 14 { 15 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2); 16 p1.value += 50; 17 p2 += 50; 18 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2); 19 } 20 } 21 22 class SomeData 23 { 24 public int value = 100; 25 }
1、在调用void Calculate(SomeData p1, int p2)方法之前,系统为v1和v2分配内存,v1的引用和v2存储在栈中,v1的数据存储在堆中(PS:手绘的图字写的丑,图也画的丑,这辈子与美术无缘)
2、开始调用方法时,v1是引用类型所以只复制了v1的引用给了p1,v1和p1同时指向堆中的同一个对象;v2是值类型,所以直接把值复制给p2
3、在方法执行的过程中,p1的value字段和p2都加上了50
4、方法执行完成后形参从栈中弹出(展开),最终v2的值没有改变,v1的值改变了。这也是值类型和引用类型中常会看到的区别。
引用参数,修饰符ref,实参必须是变量,而且必须在调用前赋值。引用参数并不会给形参在内存中开辟新的空间,它只是作为实参的一个别名,在内存中和实参指向的是同一个地址。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 SomeData v1 = new SomeData(); 6 int v2 = 30; 7 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 8 Calculate(ref v1, ref v2); 9 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 10 11 } 12 13 static void Calculate(ref SomeData p1, ref int p2) 14 { 15 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2); 16 p1.value += 50; 17 p2 += 50; 18 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2); 19 } 20 } 21 22 class SomeData 23 { 24 public int value = 100; 25 }
输出参数,修饰符out,实参也必须是变量,和引用参数有些类似,输出参数的形参也是作为实参的别名,不同的是输出参数可以不用对实参进行初始化,但是在函数调用的过程中必须对输出参数赋值,在没有赋值之前去使用形参的话是不允许的,无法通过编译。
1 static void Main(string[] args) 2 { 3 SomeData v1; 4 int v2; 5 Calculate(out v1, out v2); 6 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 7 8 } 9 10 static void Calculate(out SomeData p1, out int p2) 11 { 12 p1 = new SomeData(); 13 p1.value = 50; 14 p2 = 50; 15 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2); 16 } 17 } 18 19 class SomeData 20 { 21 public int value = 100; 22 }
引用类型作为值参数,如果将一个新的对象赋值给形参,将会切断形参和实参之间的关联
1 static void Main(string[] args) 2 { 3 SomeData v1 = new SomeData(); 4 Console.WriteLine("v1.value:{0}", v1.value); 5 Calculate(v1); 6 Console.WriteLine("v1.value:{0}", v1.value); 7 } 8 9 static void Calculate(SomeData p1) 10 { 11 p1.value = 60; 12 Console.WriteLine("p1.value:{0}", p1.value); 13 p1 = new SomeData(); 14 p1.value = 50; 15 16 Console.WriteLine("p1.value:{0}", p1.value); 17 } 18 } 19 20 class SomeData 21 { 22 public int value = 100; 23 }
如果将引用类型作为引用参数(用ref修饰符),在上面的例子中的话v1就是指向值为50的数据,并不会消除形参和实参之间的关联。这里我就不再画图了
标签:
原文地址:http://www.cnblogs.com/liunlls/p/parameter.html