浅谈引用类型和值类型,一个源代码基本可以说清楚问题:
1 class SomeRef{ public Int32 x;} 2 3 struct SomeVal{ public Int32 x;} 4 5 static void ValueTypeDemo(){ 6 SomeRef r1=new SomeRef(); 7 SomeVal v1=new SomeVal(); 8 r1.x=5; 9 v1.x=5; 10 SomeRef r2=r1; 11 SomeVal v2=v1; 12 r1.x=8; 13 v1.x=9; 14 Console.WriteLine(r1.x); 15 Console.WriteLine(r2.x); 16 Console.WriteLine(v1.x); 17 Console.WriteLine(v2.x); 18 // 8,8,9,5 19 }
因为引用类型总是从托管堆上分配的,C#的new操作符会返回对象的内存地
址,因为你每次使用一次Int32就要进行一次内存分配,性能会受到很大的影响,
所以就有能名为“值类型”的轻量级类型。值类型一般在线程栈上分配,因为值类型
并不包括一个指向实例的指针,相反,变量包含了实例本身的字段。
.NET Framework SDK文档里面清晰的说明了哪些类型是引用类型,哪些是
值类型。任何称为“类”的类型都是引用类型。文档将所有值类型都成为结构和枚举。
根据定义,所有值类型都必须从System.ValueType派生。所有枚举都从
System.Enum抽象类型派生,后者又是从System.ValueType中派生。
上面的例子中SomeRef是引用类型,所以r1,r2的值同时指向一个地址。而v1
,v2则是值类型,它只是一个包含本身字段的变量,每一个都是不同的。