/*C#值类型 ValueType * 1.有两种自定义值类型:结构,枚举; * 2.值类型(value type)和引用类型(reference type):区别源于复制策略的不同,后者又造成每种类型在内存中以不同的方式存储。值类型:直接包含值,换句话说就是引用的位置就是值在内存中 * 实际存储位置,寻址方式就是直接寻址;值类型存储在栈里面,引用类型存储在堆里面,变量名称存储在栈里面;值类型需要一个内存副本; * 值类型传值得方式是复制;引用是共享同一块内存;引用类型的变量关联了两个存储位置:直接和变量关联的存储位置,以及由变量中存储的值引用的存储位置, * 相当于是间接寻址;堆需要垃圾回收;复制引用类型的值时,只是赋值的是引用,这个引用很小,32位机是4B,64位机是8B的引用,如果复制引用 * 类型的代价比引用类型的要高的话就把这个东西设计为引用类型,要求值类型不能超过16B;除了object和string类型是引用类型,所有C#的内建类型 * 都是值类型;Use keyword struct to declare a vlaue type;declaring a reference type as a struct would create a value type larger than 16 bytes; * 3.结构不能显式的包含无参的构造函数,每个结构会自动获取一个无参的构造器将所有字段初始化为各自的默认值,默认的没有写继承自哪的话,默认继承自System.ValueType * 4.readonly只能修饰字段,是不能修饰属性的 * 5.不能在声明时为字段赋初始值;但这不是说明字段不需要初始化,除非所有的字段都初始化,否则结构类型的局部变量无法使用 * 6.为了保证值类型的局部变量被完全初始化,每个构造器都必须初始化结构中的所有字段; * 7.必须对自动实现的属性的支持字段完全赋值,才能将控制返回给调用方; * 8.方法和属性是在初始化好所有的字段才能访问,需要直接初始化好所有的字段,包括属性的支持字段; * 9.为引用类型使用new操作符,会造成“运行时”在堆上创建对象的新实例,并将所有的字段初始化为默认值,然后再调用构造器,将对该实例的引用逸this传给构造器;结果是对最终的的 * 实例的引用,该(引用)将被复制到最终的目的地; * 10.为值类型使用new操作符会造成“运行时”在临时存储池中创建对象的新实例,并将所有的字段初始化为默认值,再调用构造器(将临时存储位置作为ref变量以this传给构造器),结果 * 是临时存储位置的值,该(值)将被复制到最终的目的地; * 11.结构不支持终结器(finalize),只有类类型才能包含终结器;引用类型具有“引用同一性”,结构以值得形式复制; * 12.任何值类型都可以使用new 变量类型(); * 13.所有的值类型都隐式的密封,除了枚举类型(extends System.Enum而它继承自ValueType类)外其他的所有的值类型都派生自System.Value.这意味着就够的继承链总是从object到System.Value到结构; * 14:值类型可以实现接口; * 15.再次复习一下,在命名空间下只有两种形式:internal和public * 16.枚举类型到了CIL中就会多了一个字段就是Value__;而且每一项都是一个字段,以Int32的形式,枚举的顺序代表不同的值,所以不要再将来为枚举添加新项时插入中间,而在末尾, * 要不就是显示的赋值; * 17.enum里面的字段都会编译成static * 18.规范:不要定义结构,除非他在逻辑上代表单个值,消耗16B火更少的存储空间,不可变,而且很少装箱;枚举的主要功能是代码的可读性上面; * User: YuanWei * Date: 2015/1/19 * Time: 15:24 * */ using System; namespace LearningValueType { class Program { public static void Main(string[] args) { // TODO: Implement Functionality Here ConnectionState1[] states=(ConnectionState1[])(Array)new ConnectionState2[42]; // float fNum=23f; // byte bNum=3; // sbyte sbNum=4; int firstNum=23; int secondNum=24; // uint uiNum=24; float fNum=new float();//任何值类型都可以使用new 变量类型();跟 float FNum=0;default(int)是一样的 Console.WriteLine(fNum); Angle angle=new Angle(30,30,30); Console.WriteLine(new Program().Add(firstNum ,secondNum )); Console.ReadKey(true); } public int Add(int firstValue,int secondValue) { return firstValue+secondValue; } } public struct Angle { interface IDisplyable { //在结构中可以声明接口 } enum Sex//在结构里面默认是private { Man, Woman } // public Angle()//为隐式构造,不能显式给出; // { //报错:结构不能显式的包含无参的构造函数 // } /// <summary> ///构造函数,不能显式的包含无参的构造函数 /// </summary> /// <param name="degrees">度</param> /// <param name="minutes">分</param> /// <param name="seconds">秒</param> public Angle(int degrees,int minutes,int seconds) { _Degrees=degrees; _Minutes=minutes; _Seconds=seconds; } public int Degrees{get{return _Degrees;}}//property of Degrees private readonly int _Degrees;//Filed of _Degrees // private int Num=23;//错误:不能在声明时为字段赋初始值;但这不是说明字段不需要初始化,除非所有的字段都初始化,否则结构类型的局部变量无法使用 public int Minutes{get{return _Minutes;}} private readonly int _Minutes; public int Seconds{get{return _Seconds;}} private readonly int _Seconds; // public int Num{get;set;}//会报错:必须对自动实现的属性的支持字段完全赋值,才能将控制返回给调用方。 public Angle Move(int degrees,int minutes,int seconds) { return new Angle(Degrees+degrees,Minutes+minutes,Seconds+seconds); } // ~Angle() // { // 报错:只有类类型才能包含析构函数 // } public string ReportSex() { return (Sex.Man).ToString(); } } enum Gender//默认为internal,到了CIL中就是密闭的类,internal的话就是private,public的就是public的 { Male, Female } enum ConnectionState1 { Disconnection, Connecting, Connected, Disconnecting } enum ConnectionState2 { Disconnection, Connecting, Connected, Disconnecting } }
时间: 2024-10-15 14:11:33