一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇
二:给方法传递参数分为值传递和引用传递。
2.1在变量通过引用传递给方法时,被调用的方法得到的就是这个变量,更准确的说,是指向内存中变量的指针。所以方法内部对变量进行的任何改变在方法退出后仍然有效。而如果变量通过值传递给方法,被调用的方法得到的是变量的一个相同副本,也就是说方法退出后,对变量进行的修改会丢失。
2.2值类型的值传递:值类型的变量包含的是实际数据,作为参数传递的是数据本身的副本。如下,int类型通过值传递给方法,对应方法对该值所做的任何改变都没有改变原先int对象的值。
2.3通过引用传递值类型:传递的不是值类型的值,而是对值类型的引用,如下,参数i不是int类型,而是对num的引用,方法内部i加一时,实际是i所引用的项num。所以i加一也就修改了num的值。(个人理解是:AddOne(ref num)相当于传递了num的指针104524728,而AddOne方法中对i的操作,相当于操作指针所指向的值,即num的值)。
2.4:通过值传递引用类型。引用类型的变量不直接包含其数据,他包含的是对数据的引用。通过值传递引用类型的参数时,会改变该引用所指向的数据值,但是无法改变引用本身的值。示例代码如下:
2.4.1:下面的示例演示通过值向 AddOne方法传递引用类型的参数 str。由于该参数是对 str的引用,所以AddOne方法内的操作会更改str的值。
class Program { static void Main(string[] args) { StringBuilder str = new StringBuilder(); str.Append("hello"); AddOne(str); Console.WriteLine("num的值为:" + str);//输出值为hello,word Console.ReadKey(); } public static void AddOne(StringBuilder sb) { sb.Append(",world"); } }
2.4.2通过值传递引用类型时,试图将参数重新分配到不同的内存位置时,该操作仅在方法内有效,并不影响原始变量。如下代码:
class Program { static void Main(string[] args) { StringBuilder str = new StringBuilder(); str.Append("hello"); AddOne(str); Console.WriteLine("str的值为:" + str);//输出值为hello Console.ReadKey(); } public static void AddOne(StringBuilder sb) { sb = new StringBuilder(); sb.Append(",world"); } }
2.5:通过引用传递引用类型。其实是传递其引用地址的引用,类似于指针的指针。引用传递引用类型如果创建一个新的实例会影响原来的引用类型。代码如下
class Program { static void Main(string[] args) { StringBuilder str = new StringBuilder(); str.Append("hello"); AddOne(ref str); Console.WriteLine("str的值为:" + str);//输出值为,world Console.ReadKey(); } public static void AddOne(ref StringBuilder sb) { sb = new StringBuilder(); sb.Append(",world"); } }
三:关于值类型和引用类型的转换可看下一篇:
C#学习笔记(基础知识回顾)之值类型与引用类型转换(装箱和拆箱)