Net面向对象程序设计-9-使用枚举和结构来创建值类型-2010-2011-2.ppt
1,孙月江 syjsdut163.com,1,第9章 理解值和引用使用枚举和结构来创建值类型,声明枚举类型 创建并使用枚举类型 声明结构类型 创建结构和类在行为上的差异,在C#中可以使用const来创建常量,例如: const pi=3.14 lightOfSpeed=3*108 缺点:只能表达一个常量 如何表达有限数量的常量集,9.1 使用枚举,例如,在程序中表示: 一年四季Season:可以使用整数0,1,2,3分别表示Spring、Summer、Fall、Winter 颜色:Red、Bule、Yellow、White 一周:Sunday、Monday、 假如声明变量Season为int,不止1,2,3,0,所有的整数值都可以赋给它 C#中,可以使用enum关键字创建一个枚举类型,限制其值只能是一组符号名称,9.1.1 声明枚举,枚举的声明方式 enum Season Spring, Summer, Fall, Winter 说明 Season是一个新定义类型的名字,它称为枚举 使用.操作符,Season.Spring是int类型值0的符号常量,Spring.Summer是int类型值1的符号常量,9.1.2 使用枚举,enum Season Spring, Summer, Fall, Winter class Example public void Method(Season parameter) Season localVariable; . private Season currentSeason; ,枚举类型的变量只有在赋值后才能使用 只能将枚举类型定义的值赋给一个枚举变量 例如: Season colorful =Season.Fall; Console.WriteLine(colorful);/输出fall 和所有值类型一样,可以使用?修饰符来创建一个可空的枚举变量 这样,除了可以把枚举类型定义的值赋给这个变量,还可以把null值赋给它 例如: Season ?colorful=null,9.1.3 使用枚举文字常量值,枚举的内部,它的每个元素对应着一个整数值,默认情况下,第一个元素对应整数0,以后的每个元素所对应的整数都递增1. 若要获得一个枚举变量的基础整数值,必须进行转换 enum Season Spring, Summer, Fall, Winter . Season colorful = Season.Fall; Console.WriteLine(int)colorful); / writes out '2,也可以把一个特定的整数常量和一个枚举的文字常量关联起来 例如: enum Season Spring = 1, Summer, Fall, Winter 多个枚举文字常量可以拥有相同的基础值 例如:秋天 英国Autumn,美国Fall enum Season Spring, Summer, Fall, Autumn = Fall, Winter ,9.1.4 选择枚举的基本类型,枚举的文字常量默认为int类型,但是可以选择让枚举类型基于一种不同的基本整数类型 例如: enum Season : short Spring, Summer, Fall, Winter ,总结:枚举类型的优点,用枚举类型提高可读性: 没有枚举功能的语言通常要依靠易出错、不清晰的结构来表达成组的常量。 例如,为了表达上面提到的5个颜色值,常用的过程表达为“1代表green、2代表red、3代表blue等等”。在这种情况下,若要检查wall的颜色是否为green,对应的jf语句为: if(wall= =1)不清楚1代表的颜色 而不是:if(Wall= =Color.Green) 无需额外的注释,后者更清楚而且容易直观理解. 总之,为了提高源代码的清晰度和自解释性,当在编译前已经知道了一个变量的所有可能值时应尽量使用枚举。,课本158页练习,9.2 使用结构,类定义的是一个引用类型,它总是在堆上建立 某些时候,类中只包含极少的数据,因为管理堆所造成的开销显得极不合算 可以将类型定义成一个结构 结构是值类型,在栈上存储,所以能更有效的减少内存管理的开销 结构也可以包含自己的字段、方法和构造器,常用的结构类型 基本数值类型int,long,float分别是System.Int32,System.Int64,System.Single这三个结构类型的别名 所有这些结构有自己的字段和方法,可以直接为这些类型的变量和文字常量调用方法,例如: int i = 99; Console.WriteLine(i.ToString(); Console.WriteLine(55.ToString(); float f = 98.765F; Console.WriteLine(f.ToString(); Console.WriteLine(98.765F.ToString();,更为常见的是使用这些结构的静态方法 string s = “42“; int i = int.Parse(s); / exactly the same as Int32.Parse 这些结构还包含一些有用的静态字段,例如:Int32.MaxValue,Int32.MinValue,9.2.1 声明结构,struct Time public int hours, minutes, seconds; 尽量不要把结构的字段声明为public,可以通过为结构添加构造器和方法初始化和处理这些字段 struct Time public Time(int hh, int mm, int ss) hours = hh % 24; minutes = mm % 60;seconds = ss % 60; public int Hours() return hours; . private int hours, minutes, seconds; ,结构主要适用于实现“值”的概念 对于简单的、比较小的数据值,如果复制值的效率等同于或者基本等同于一个地址的效率,就是用结构 对于较复杂的数据,就考虑使用类,9.2.2 理解结构和类的区别,不能为结构声明默认的构造器,因为编译器始终会帮我们生成一个 struct Time public Time() . / compile-time error . 在编译器为结构生成的默认构造器中,总是将字段设为0,false或者null 假如不使用默认的构造器,还可以提供一个非默认的构造器,用它将字段初始化不同的值 在自己写的一个构造器中,必须自己负责初始化所有的字段,编译器不会再帮我们初始化。,即,必须在结构的所有非默认构造器中显式地初始化所有字段,否则会造成编译器错误 struct Time private int hours, minutes, seconds; . public Time(int hh, int mm) this.hours = hh; this.minutes = mm; / compile-time error: seconds not initialized ,在一个类中,可以在声明一个实例字段的同时初始化它,但在结构中不允许这么做 struct Time private int hours = 0; / compile-time error private int minutes; private int seconds; . ,阅读课本163页,类和结构的主要区别表,9.2.3 声明结构变量,struct Time private int hours, minutes, seconds; . class Example private Time currentTime; public void Method(Time parameter) Time localVariable; . ,可以使用?修饰符创建一个结构变量的可空版本,然后把null值赋给这个变量 Time? currentTime = null;,9.2.4 理解结构的初始化,如果调用一个构造器,则结构中的所有字段都将得到初始化 Time now = new Time(); 由于结构是值类型,所以不需要调用构造器就可以创建结构变量 Time now;,在自己的构造器中,必须显式初始化一个struct的所有字段 struct Time private int hours, minutes, seconds; . public Time(int hh, int mm) hours = hh; minutes = mm; seconds = 0; ,Time now = new Time(12,30);,课本165页练习,9.2.5 赋值结构变量,如果一个struct变量已经完全初始化,就可以将它赋值给另一个struct变量 Time now = new Time(12, 30); Time copy = now; 下例无法通过编译 Time now; Time copy = now 复制一个结构变量时,=操作符左侧的结构变量的每个字段直接从右侧结构变量的相应字段中复制 如果是一个类,两个变量将引用堆上同一个变量,23,课本168页练习,24,