一、引言

  对于一些初学者(包括工作几年的人在内)来说,有时候对于方法之间的参数传递的问题感觉比较困惑的,因为之前在面试的过程也经常遇到参数传递的基础面试题,这样的面试题主要考察的开发人员基础是否扎实,对于C#中值类型和引用类型有没有深入的一个理解——这个说的理解并不是简单的对它们简单一个定义描述,而在于它们在内存中分布。所以本文章将带领大家深入剖析下C#中参数传递的问题,并分享我自己的一个理解,只有你深入理解了才能在不运行程序的情况可以分析出参数传递的结果的。

  二、按值传递

  对于C#中的参数传递,根据参数的类型可以分为四类:

  ● 值类型参数的按值传递

  ● 引用类型参数的按值传递

  ● 值类型参数的按引用传递

  ● 引用类型参数的按引用传递

  然而在默认情况下,CLR方法中参数的传递都是按值传递的。为了帮助大家全面理解参数的传递,下面这四种情况一一进行分析。

  2.1 值类型参数的按值传递

  对于参数又分为:形参和实参,形参指的是被调用方法中的参数,实参指的是调用方法的参数,下面结合代码帮助大家理解形参和实参的概念:

class Program
    {
        static void Main(string[] args)
        {
                                           
            int addNum = 1;
            // addNum 是实参,
            Add(addNum);
         }
        // addnum是形参,也是被调用方法中的参数
        private static void Add(int addnum)
        {
            addnum = addnum + 1;
            Console.WriteLine(addnum);
        }
}

  对于值类型的按值传递,传递的是该值类型实例的一个拷贝,也是形参此时接受到的是实参的一个副本,被调用方法操作是实参的一个拷贝,所以此时并不影响原来调用方法中的参数值,为了证明这点,看看下面的代码和运行结果明白了:

class Program
    {
        static void Main(string[] args)
        {
            // 1. 值类型按值传递情况
            Console.WriteLine("按值传递的情况");
            int addNum = 1;
            Add(addNum);
            Console.WriteLine(addNum); 
                                    
            Console.Read();
        }
        // 1. 值类型按值传递情况
        private static void Add(int addnum)
        {
            addnum = addnum + 1;
            Console.WriteLine(addnum);
        }

  运行结果为:

  从结果中可以看出addNum调用方法之后它的值并没有改变,Add 方法的调用只是改变了addNum的副本addnum的值,所以addnum的值修改为2了。然而我们的分析到这里并没有结束,为了让大家深入理解传递传递,我们有必要知道为什么值类型参数的按值传递不会修改实参的值,相信下面这张图可以解释你所有的疑惑: