C#基础整理参数

基本概念

  把数据传入方法中,可以使方法有多个返回值。

参数的传递

  值参数,通过将实参的值复制到形参的方式传递数据。值参数的实参可以是变量或者是表达式

下面是一个简单的值参数传递的过程

 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的数据,并不会消除形参和实参之间的关联。这里我就不再画图了

 

posted @ 2015-04-11 10:58  高效养猪倌  阅读(554)  评论(4编辑  收藏  举报