值类型和引用类型
值类型
值类型是直接分配在栈上的空间,这个空间对应着值类型变量的值。
引用类型
引用类型是分配在堆上的空间,这个空间对应着引用类型的内存分配地址。
在别人的博客里看到一句话形容是“值类型是现金,引用类型是存折”。觉得没什么毛病,使用值类型修改它的值,是直接对这个变量操作的,而使用引用类型,则是先取到它在内存中分配的地址指向的值。
public class Person
{
public string name;
public int age;
}
class Main
{
static void main()
{
Person jerry = new Person
{
name = "jerry";
age = 18;
};
Person tom = new Person
{
name = "tom";
age = 20;
}
int age = jerry.age;
jerry.age = 19;
Person shawn = tom;
tom.name = "TOOOOM";
Console.WriteLine("age:{0}", age);
Console.WriteLine("jerry.age:{0}", jerry.age);
Console.WriteLine("shawn.name:{0}", shawn.name);
Console.WriteLine("tom.name:{0}", tom.name);
}
}
age:18
jerry.age:19
shawn.name:TOOOOM
tom.name:TOOOOM
age的值并没有随着jerry.age的值变化而变化,但是shawn.name却因为tom.name的变化而改变了。因为class是引用类型,它们指向的是内存中的同一个地址,在tom修改了name的值之后,shawn再访问这片内存地址,得到的值也是修改后的。
在声明age的时候,便在栈上开辟了一片空间,然后把jerry.age的值填了进去。但是在声明shawn的时候,是在堆上开辟了一片空间,然后tom是一个引用类型,然后把tom的引用传递给了shawn,所以在修改了tom.name之后,shawn.name也跟着改变。
在性能上,值类型是直接操作内存的处理,而引用类型则多了一个内存地址的解析,很多时候值类型会减少系统性能的开销,但是也有例外,在进行大量的函数变量的传递和返回时,频繁的字段拷贝,也是反而会降低系统性能的。如果字段被频繁的用户HashTable或者ArrayList,这些类会对其中的值类型进行装箱操作,也会导致而外的内存分配和内存拷贝,对性能也是有影响的。