当前位置: 代码迷 >> C# >> C#基础拾掇参数
  详细解决方案

C#基础拾掇参数

热度:70   发布时间:2016-05-05 04:13:10.0
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 SomeData23     {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 SomeData23     {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 SomeData20     {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 SomeData21     {22         public int value = 100;23     }

 

 

如果将引用类型作为引用参数(用ref修饰符),在上面的例子中的话v1就是指向值为50的数据,并不会消除形参和实参之间的关联。这里我就不再画图了

 

  相关解决方案