第3章           C#程序入门

Windows XPWindows Vista中,控制台窗口被称为命令提示。

 

//开头的注释被称为单行注释(single-line comment),这是因为注释到它所在行的末尾就结束了。定界注释(delimited comment)形如:

/* This is a delimited comment.

It can be split over many lines */

这种类型的注释以定界符/*开头,以定界符*/结尾,两个定界符之间的所有文本都会被编译器忽略。

 

类按照名字空间(namespace)组织,名字空间即相关类得命名集合。.NET的名字空间统称为.NET框架类库(FCL)。每个using指令都指定一个名字空间,它包含C#程序可以使用的预定义类。

 

空行、空格符和制表符统称为空白符(whitespace)。空格符和制表符又特称为空白字符(whitespace character)。

通过使用新行符(newline character),可以用单条语句显示多行文本。

 

每个程序至少又一个由程序员定义的类声明,称为用户定义类。

关键字也称保留字,全部采用小写字母。C#是大小写敏感的。

 

按照惯例,所有类名都以大写字母开头,包含的每个单词的第一个字母都大写。类名是一个标识符,它由字母、数字和下划线组成,不能以数字开头,也不能包含空格。

 

标识符前面还可加上@号。这个符号表示单词应当解释为标识符,即使它为关键字。这样,就可使C#代码能使用其他.NET语言编写的代码,即使它的标识符与C#的关键字同名。

 

当保存文件中的public类声明时,文件名通常和类名相同,再加上.cs文件扩展名。包含一个公有类得文件命名时应和类同名(加上.cs扩展名),拼写和大小写都一致。这样命名文件有助于其他程序员(以及创建者本人)更易确定程序的类所在的位置。

 

选择Edit>Advanced>Format Document,可以让IDE格式化代码。

 

当编译器报告语法错误时,错误可能并不在错误消息所指的行中。首先,要检查报告错误的行。如果该行没有语法错误,则要检查前面的几行。

一个语法错误可能导致在Error List窗口中出现多条错误消息。改正一个错误后,重新编译程序时可能会消除多个后续的错误消息。

 

在结束一个方法体或类声明的右大括号之后,添加一个注释,指出它所属的方法或类声明,能提高程序的可读性。

 

IDE使用的代码配色模式称为语法颜色高亮(syntax-color highlighting)。

 

智能感应(IntelliSense),它会列出类得成员,包括方法名。显示智能感应窗口时,按Ctrl键可以使窗口透明,以便能看到窗口后面的代码。按Esc键关闭参数信息窗口。

 

根据代码的类型,编译器可能将它编译成.exe(可执行)文件、.dll(动态链接库)文件或带其他扩展名的文件。这些文件被称为汇编(assembly),是编译C#代码的包装单元。这些汇编包含程序的Microsoft中间语言(MSIL)代码。

 

在完全版的Visual Studio 2008中,可以从IDE顶部工具栏的Solution Configuration下拉清单中选择希望建立的特定版本,默认情况是Release版本。

 

反斜线(\)称为转义符(escape character),它向C#标明这是字符串中的一个“特殊字符”。当字符串中出现反斜线时,C#将反斜线与之后的下一个字符组成一个转义序列(escape sequence)。

转义序列

描述

\n

新行符。将光标移到下一行开头。

\t

水平制表符。将光标移到下一制表位。

\r

回车符。将光标移到当前行开头。回车符后面输出的任何字符,都会覆盖该行中以前输出的字符。

\\

反斜线

\”

双引号

 

当方法要求多个变元时,它们会出现在逗号分隔清单(comma-separated list)中。

格式串(format string)由固定文本和格式项组成。每个格式项都是一个值的占位符。格式项放在大括号中,它包含的字符序列告诉方法用什么变元,如何格式化。例如,格式项{0}是此后第一个变元的占位符(C#0开始计数)。

 

应在单独的行中声明每个变量。这种格式使得容易在每个声明之后插入注释。应选择有意义的变量名,可使代码具有自说明性(self-documenting)。

 

按照惯例,变量名标识符以小写字母开头,并且第一个单词之后的每个单词都用大写字母开头。这种命名惯例被称为骆驼规则(camel casing)。

 

赋值运算符被称为二元运算符(binary operator),因为它对两块信息进行操作。这些信息块被称为操作数(operand)。

 

赋值语句(assignment statement)。

赋值运算符右侧的任何内容,总是在赋值执行之前计算。除了赋值运算符之外,所有的运算符都是从左到右结合的。

 

空语句(empty statement),分号独占一行。

 

将标识符、字符串或多字符运算符(比如>=)分开写是不正确的。

 

3.9   软件工程案例研究:分析ATM需求文档

为了了解系统应当作什么,开发人员常常采用一种称为用例建模(use case modeling)的技术。

 

系统结构描述了系统的对象以及它们的相互关系,系统行为描述了对象间交互时系统如何变化。每个系统都有结构和行为。

 

UML标准中定义了13种框图类型,说明不同的系统模型。每种类型都建模了系统的结构或行为的不同特性——其中6种框图与系统结构有关,另外7种与系统行为有关。

这些框图包括:

1.  用例框图(use case diagram)。它建模系统与外部实体(角色)之间的交互。

2.  类框图(class diagram)。有助于指明系统各部分间的结构性关系。

3.  状态机框图(state machine diagram)。它建模对象改变状态的途径。

4.  活动框图(activity diagram)。它建模对象的活动——在执行程序期间对象的工作流(事件序列)。

5.  通信框图(communication diagram)。在早期的UML版本中,它称为协作框图()。它建模系统中对象间的交互,强调的是发生了哪种交互。

6.  顺序框图(sequence diagram)。也建模系统中对象间的交互,强调的是何时发生交互。

7.  对象框图。建模系统的“快照”,即建模特定时刻的系统对象及其关系。每个对象都代表类框图中一个类得实例,一个类可以创建多个对象。

8.  组件框图。建模构成系统的组件和资源(包括源文件)。

9.  部署框图。建模系统的运行时需求(如系统所在的计算机)、内存需求以及系统执行时所要求的其他设备。

10. 包框图。建模编译时系统中包(即类组)的层次结构,以及包间的关系。

11. 合成结构框图。建模运行时复杂对象的内部结构。合成结构框图是UML2中新增的,它使系统设计员可以按照层次将复杂对象分解为小部件。

12. 交互概要框图。它也是UML2中新增的,组合几种类型的行为框图元素(如活动框图、顺序框图)。

13. 定时框图。也是UML2新增的,它建模系统中对象间交互和阶段改变的时间约束。

 

第4章           简要介绍类和对象

访问修饰符(access modifier)确定了程序中其他方法能否访问对象的属性和方法。

 

静态方法是一种特殊方法,因为不必先创建声明该方法的类的对象,即可直接调用它。

 

构造函数与方法相似,但能够在创建对象时,用于初始化对象的数据。

 

通常而言,对象是用关键字new创建的。一个例外情况时包含在双引号中的字符串字面值,如“hello”。字符串字面值是对C#隐含创建的字符串对象的引用。

 

方法调用中的变元个数必须与被调用的方法声明参数表中的参数个数相同。而且,方法调用中的变元类型,必须与方法声明中对应的参数类型兼容。

 

在同一个工程中编译的类在同一个名字空间中。没有显示放入某个名字空间的任何类,都被隐含放入所谓的全局名字空间中。

 

类得完全限定类名(fully qualified class name)包含完整的名字空间和类名。Visual C# Form Designer产生的代码使用完全限定类名。

 

在方法体中声明的便利称为局部变量(local variable),它们只能用在这个方法中。当方法终止时,局部变量的值就丢失了。属性在类声明中用变量表示。这样的变量被称为字段(field),它是在类声明的内部声明的,但位于类得方法声明体之外。当类得每个对象维护自己的属性副本时,代表属性的字段又称为实例变量——类得每个对象(实例)在内存中有该变量的一个单独实例。

 

private访问修饰符声明的变量、属性或方法,只能由声明它们的类的属性和方法访问。如果省略类成员前面的访问修饰符,则这个成员隐式声明为private。用访问修饰符private声明实例变量的方法,被称为信息隐藏(information hiding)。

 

自实现属性(auto-implemented property)。对于自实现属性,C#编译器自动创建私有实例变量以及返回和修改这个私有实例变量的getset访问方法。形如:

public class GradeBook

{

public string CourseName {get; set;}

}

默认情况下,属性的setget访问方法与属性的访问类型相同。例如,公有属性的访问方法也是公有的。但也可以用不同的访问修饰符声明getset访问方法。这时,必须将一个访问方法显式声明为与属性的访问类型相同,将另一个访问方法用访问修饰符声明得比属性更严格。

 

IDE的代码段(code snippet)特性可以在源代码中插入预定义模板。其中一个代码段可以插入公有自实现属性,只要在代码窗口中键入单词“prop”并按Tab键两次即可。插入的代码段会高亮显示,以便能方便地改变属性的类型和名称。可以按Tab键从一个高亮显示的代码段移到另一代码段。默认情况下,新属性的类型为int,名称为MyProperty。要取得所有代码段的列表,可按Ctrl+KCtrl+X组合键,从而在代码编辑器中打开Insert Snippet窗口。这个特性也可以这样访问:右击源代码编辑器并从菜单中选择Insert Snippet菜单项。

 

C#中的类型分为两类——值类型(value type)和引用类型(reference type)。C#的简单类型都是值类型。值类型的变量只包含这个类型的值。相反,引用类型的变量(有时也称为引用)包含存储变量所引用数据的内存地址。这样的变量被认为是在程序中“引用对象”(refer to an object)。

如果变量类型不是13种简单类型之一或enumstruct类型,则它就是引用类型。

 

对于没有显示定义构造函数的类,编译器提供一个不带参数的公有默认构造函数,因此每个类都有构造函数。默认构造函数不修改实例变量的默认值(值类型为0,布尔类型为假,引用类型为null)。与方法不同,构造函数不指定返回类型。通常,构造函数被声明为公有的。只要程序员为类声明了构造函数,C#就不会为该类创建默认构造函数。

 

C#为存储实数提供了三个简单类型:floatdoubledecimalfloatdouble类型称为浮点类型,它们与decimal的主要差别在于:decimal变量精确存储有限范围的实数,而浮点数值存储实数的近似值,但取值范围大得多。而且,与float变量相比,double变量存放的数更大,并且更精确,即小数点右边的位数可以更多。这些位数又称为精度(precision)。decimal类型的一个主要应用是表示金额。

float类型的变量表示单精度浮点数(single-precision floating-point number),有7位有效数字。double类型的变量表示双精度浮点数(double-precision floating-point number)。double变量需要的内存量是float变量的两倍,有15~16位有效数字——大约是float变量的精度的两倍。此外,decimal类型变量需要double变量两倍的内存,提供28~29位有效数字。

默认情况下C#将程序源代码中的所有实数都看成是double值。源代码中的此类值被称为“浮点字面值”(floating-point literal)。要输入decimal字面值,就要在实数的末尾加上“M”或“m”字样。整数字面值赋值给floatdoubledecimal类型的变量时,隐式转换成这些类型。

 

格式项“{0:C}”——0后面的冒号表示下一个字符是格式指定符(format specifier),冒号后面的格式指定符C指定金额值(C指币值,currency)。

格式指定符

描述

Cc

将字符串格式化为币值。在数字前面加上相应的货币符号(美国为$)。数字用合适的分隔符分开(美国为逗号),默认将小数位设置为两位

Dd

将字符串格式化为小数。将数字显示为整数

Nn

将字符串用千分位格式化。默认带两位小数

Ee

将用科学计数法格式化。默认带六位小数

Ff

用固定小数位格式化字符串。默认为两位

Gg

根据上下文将数字格式化成小数位或使用科学计数法。如果格式项不包含格式指定符,则隐式设定为G

Xx

将字符串格式化为十六进制值

 

 

UML

UML中,每个类在类框图中被建模成带三个栏的矩形。顶部栏中包含类名,水平居中并以粗体显示。中间栏包含类的属性,对应于C#中的实例变量和属性。底部栏包含类的操作,对应于C#中的方法。操作名前面的加号标明此方法在UML中是一个公有操作。加号有时也被称为公有可见性符号(public visibility symbol)。

 

UML建模参数是在操作名之后的圆括号中列出参数名,后接一个冒号和参数类型。

 

在书名号中使用描述性单词(UML中称为版型,stereotype)有助于区别不同类型的属性与操作。

 

4.12          软件工程案例研究:确定需求文档中的类

UML允许类的属性和操作以压缩方式显式(不划分成栏的矩形),以创建可读性更强的框图。这样的框图被称为省略框图(elided diagram),在其中并不建模某些信息。

连接连个累的实线代表关联(association)——类之间的关联。靠近每条线末端的数字是重数值(multiplicity),它表示参与关联的每个类的对象有多少。

符号

含义

0

1

1

m

整数值

0..1

01

m, n

mn

m..n

至少m,但不超过n

*

任何非负整数(0或多个)

0..*

0个或多个

1..*

1个或多个

 

当关联的含义不需要角色名也显而易见时,经常会省略类框图中的角色名(角色名是关联线旁的单词,指一个对象在与另一个对象的关系中所扮演的角色)。

 

合成关系隐含了整体/部分关系。在关联线末端有合成符号(实心菱形)的类就是整体,另一端的类就是部分。

根据UML规范,合成关系具有如下属性:

1. 只有关系中的一个类能代表整体(即,菱形只能放在关联线的一端)。

2. 合成关系中的部分只能与整体存在同样长的时间,并且整体负责部分的创建和销毁。

3. 一个部分一次只能属于一个整体,但这个部分可以被去掉并连接到另一个整体,然后可以继续担当这个部分的职责。

类框图中的实心菱形标明了实现这三个属性的合成关系。如果“有”关系不满足这个三条准则中的任何一条,则UML指定在关联线末端加空心菱形,表示聚合(aggregation),这是一种更弱的合成形式。