对于为什么原来的值没有被改变主要是因为string的“不变性”,所以在被调用方法中执行 oldStr="New string"代码时,此时并不会直接修改oldStr中的"old string"值为"New string",因为string类型是不变的,不可修改的,此时内存会重新分配一块内存,然后把这块内存中的值修改为 “New string”,然后把内存中地址赋值给oldStr变量,所以此时str仍然指向 "old string"字符,而oldStr却改变了指向,它后指向了 "New string"字符串。所以运行结果才会像上面这样,下面内存分布图可以帮助你更形象地理解文字表述:

  三、按引用传递

  不管是值类型还是引用类型,我们都可以使用ref 或out关键字来实现参数的按引用传递,然而按引用进行传递的时候,需要注意下面两点:

  方法的定义和方法调用都必须同时显式使用ref或out,否则会出现编译错误

  CLR允许通过out 或ref参数来实现方法重载。如:

#region CLR 允许out或ref参数来实现方法重载
        private static void Add(string str)
        {
            Console.WriteLine(str);
        }
        // 编译器会认为下面的方法是另一个方法,从而实现方法重载
        private static void Add(ref string str)
        {
            Console.WriteLine(str);
        }
        #endregion

  按引用传递可以解决由于值传递时改变引用副本而不影响引用本身的问题,此时传递的是引用的引用(也是地址的地址),而不是引用的拷贝(副本)。下面具体看看按引用传递的代码:

class Program
    {
        static void Main(string[] args)
        {
            #region 按引用传递
            Console.WriteLine("按引用传递的情况");
            int num = 1;
            string refStr = "Old string";
            ChangeByValue(ref num);
            Console.WriteLine(num);
            changeByRef(ref refStr);
            Console.WriteLine(refStr);
            #endregion
            Console.Read();
        }
        #region 按引用传递
        // 1. 值类型的按引用传递情况
        private static void ChangeByValue(ref int numValue)
        {
            numValue = 10;
            Console.WriteLine(numValue);
        }
        // 2. 引用类型的按引用传递情况
        private static void changeByRef(ref string numRef)
        {
            numRef = "new string";
            Console.WriteLine(numRef);
        }
        #endregion
}

  运行结果为:

  从运行结果可以看出,此时引用本身的值也被改变了,通过下面一张图来帮忙大家理解下按引用传递的方式:

  四、总结

  到这里参数的传递所有内容介绍完了。总之,对于按值传递,不管是值类型还是引用类型的按值传递,都是传递实参的一个拷贝,只是值类型时,此时传递的是实参实例的一个拷贝(也是值类型值的一个拷贝),而引用类型时,此时传递的实参引用的副本。对于按引用传递,传递的都是参数地址,也是实例的指针。