C#中有两大类数据类型——引用类型和值类型。在内存中存储是不一样的。
引用类型:类、接口、委托。
值类型:结构体、枚举。
创建一个新的变量,引用类型就new,值类型就int(int32结构体类型),不完全准确但是就大概这个道理。
好我们继续,参数也分成两大类:传值参数和引用参数。声明时候不带任何修饰符就属于值参数,会创建实际参数的副本。引用参数不会为传进来的参数创建副本,直接指向方法调用时候的作为实际参数传进来的变量的地址。
然后结合,就有了很令人头疼的四个东西:
值类型值参数
引用类型值参数
值类型引用参数
引用类型引用参数
慢慢来一个一个讲。
值类型传值参数 创建新变量:只影响方法体内副本的值,外面的变量原值不变。
引用类型传值参数 创建新变量:引用类型变量存储的就是一个地址。在方法内部为参数给了一个新值(new),相当于把一个新对象交给参数,而外面那个还是引用的原来的地址。
值类型引用参数:参数与变量指向同一个地址。当参数获得新值,方法外也是获得这个新值,“故意”改变外面的参数的值。
引用类型的引用参数:参数变量指向同一个地址,这个地址存贮的是对象在堆内存中的地址。
引用参数不好理解,再看看:
引用类型值参数:创建实际参数副本,stu和outterstu指向不同地址,但是两个地址存储一个东西,就是变量在堆内存的地址。好比有两袋洗衣粉,stu和outterstu分别指向410 423房间,恰好这两个房间放置着两袋相同的洗衣粉。所以值不变hash不变,但是归根到底是2个房间。
引用类型引用参数:不创建实际参数副本,stu和outterstu直接指向同一个地址,这个地址存储变量在堆内存的地址。这时候stu和outterstu都指向410,410里面有一个洗衣粉。值不变hash不变,因为指向同一个房间的同一袋洗衣粉,当然不变了(废话)。