值类型与引用类型

来源:互联网 发布:重庆网络推广产品代理 编辑:程序博客网 时间:2024/06/05 06:50

直白点儿说:值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。    ——麦机长

我觉得这话十分形象。

声明一个值类型变量,编译器会在栈上分配一个空间,这个空间对应着该值类型变量,空间里存储的就是该变量的值。引用类型的实例分配在堆上,新建一个引用类型实例,得到的变量值对应的是该实例的内存分配地址,这就像银行账号一样。

 1: public class Person   2: {   3:     public string Name { get; set; }   4:     public int Age { get; set; }   5: }   6:     7: public static class ReferenceAndValue   8: {   9:     public static void Demonstration()  10:     {  11:         Person zerocool = new Person { Name = "ZeroCool", Age = 25 };  12:         Person anders = new Person { Name = "Anders", Age = 47 };  13:    14:         int age = zerocool.Age;  15:         zerocool.Age = 22;  16:    17:         Person guru = anders;  18:         anders.Name = "Anders  Hejlsberg";  19:    20:         Console.WriteLine("zerocool's age:\t{0}", zerocool.Age);  21:         Console.WriteLine("age's value:\t{0}", age);  22:         Console.WriteLine("anders' name:\t{0}", anders.Name);  23:         Console.WriteLine("guru' name:\t{0}", guru.Name);  24:     }  25: }
zerocool和anders这两个对象都被分配在堆上,而zerocool和anders本身其实只是对象所在内存区域的起始地址引用,换句话说就是指向这里的指针。而age是值类型,编译器在栈上给他分配了一块空间,这里的赋值给age,则是将zerocool的age值放到了那个空间中。而guru是引用类型,他所对应的赋值,则是将Anders的堆上的数据地址引用赋值给了guru,则guru和Anders指向了同一个地方。


C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型。C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。数组的元素,不管是引用类型还是值类型,都存储在托管堆上。
1.C#的所有值类型均隐式派生自System.ValueType。
各个值类型及其基类:
结构体:struct(直接派生于System.ValueType);

数值类型:
整型:
shortSystem.Int16),
ushortSystem.UInt16),intSystem.Int32),uintSystem.UInt32
longSystem.Int64),
ulongSystem.UInt64),
sbyte(System.SByte的别名),byteSystem.Byte),
字符型:charSystem.Char);
浮点型:floatSystem.Single),doubleSystem.Double);

用于财务计算的高精度decimaldecimalSystem.Decimal)。
bool
boolSystem.Boolean的别名);

枚举:enum(派生于System.Enum);
可空类型(派生于System.Nullable泛型结构体,语法 T? 是 System.Nullable<T> 的简写,此处的 T 为值类型。)

2.C#的所有引用类型均隐式派生自System.object。
各个引用类型及其基类:
数组:(派生于System.Array数组的元素,不管是引用类型还是值类型,都存储在托管堆上
类:class(派生于System.Object);
接口:
interface(接口不是一个“东西”,所以不存在派生于何处的问题。);
委托:
delegate(派生于System.Delegate);
object
System.Object的别名);

字符串:stringSystem.String的别名)。

0 0
原创粉丝点击