项目任务实施
任务1 C#应用程序开发
一、任务描述
C#是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言。如果需要开发Windows桌面应用程序、Windows Store应用程序、Web应用程序、WCF服务等,项目建设者必须掌握C#编程语言。
二、问题引导
(1)C#程序开发环境如何搭建与配置?
(2)如何编写、编译、运行和注释一个简单的C#程序?
三、知识准备
1.软件开发基本流程
软件开发流程即软件设计思路和方法的一般过程。软件开发过程(software development process),或软件过程(software process),是软件开发的生命周期,其各个阶段分别实现了软件的需求定义与分析、设计、实现、测试、交付和维护。软件过程是在开发与构建系统时应遵循的步骤,是软件开发的路线图。
按照不同阶段的任务安排,包括对软件进行需求分析、设计软件的功能及实现该功能的算法和方法、软件的总体结构设计和模块设计、编码和调试、程序联调和测试以及编写、提交程序等一系列操作以满足客户的需求并且解决客户的问题,如果有更高的需求,还需要对软件进行维护、升级和报废处理。从管理的角度来看,即从业务和经济的角度来看,软件的生命周期包括4个主要阶段:
(1)起始阶段——在一个好的想法的基础上构思出产品及其业务案例,确定项目的范围。
(2)细化阶段——计划活动和所需资源,确定功能并设计架构。
(3)构建阶段——发展最初的设想、架构和计划,直到产品完整实现。
(4)移交阶段——将产品移交给用户使用,包含制造、交付、培训、支持、维护等内容。
这4个阶段称为一个开发周期,其所产生的软件称作第一代。现有产品能够通过演进,重复下一个起始、细化、构建和移交过程,各阶段的侧重点与第一代不同,从而演进出下一代产品,直到产品终结。最后产品经过几个周期的演进,新一代产品也不断被制造出来。演进周期的启动可能是由于用户建议增强功能、用户环境改变、重要技术变更,以及应对竞争的需要。实际中,周期之间会有轻微重叠。比如起始阶段和细化阶段可能在上一个周期的移交阶段未结束时就已开始。项目生命周期模型是刻画一个工程从起始到完成,是如何进行计划、控制和监控的模型,表1-1所示为常见的项目生命周期模型。
表1-1 常见的项目生命周期模型
(1)快速原型模型:是原型模型在软件分析、设计阶段的应用,用来解决用户对软件系统在需求上的模糊认识,或用来试探某种设计是否能够获得预期结果。在开发真实系统之前,通过构建一个可以运行的软件原型,使开发人员与用户达成共识,以便加强理解和澄清问题,最终在确定的客户需求的基础上开发让客户满意的软件产品。
快速原型模型具有以下特点:
①快速原型模型的作用是获取用户需求,或用来试探设计是否有效。一旦需求或设计确定下来,原型将被抛弃。因此,快速原型模型要求快速构建、容易修改,以节约原型创建成本、加快开发速度。目前,Microsoft Visual Basic、Inprise Delphi等基于组件的可视化开发工具,都是非常有效的快速原型创建工具。
②快速原型模型是暂时使用的,因此并不要求完整。它往往针对某个局部问题建立专门原型模型,如界面原型模型、工作流原型模型、查询原型模型等。
③快速原型模型不能贯穿软件的整个生命周期,它需要和其他的过程模型结合使用才能发挥作用,如在瀑布模型中应用快速原型模型,以解决瀑布模型在需求分析时期存在的不足。
(2)瀑布模型:将软件生存周期的各项活动规定为按固定顺序连接的若干阶段,如瀑布流水,每个阶段都会产生循环反馈,将上一项活动的输出作为该项活动的输入,如果有信息未被覆盖或者发现问题,会“返回”上一阶段并进行适当的修改,项目开发进程从一个阶段“流动”到下一个阶段,这也是瀑布模型名称的由来。
图1-1所示为瀑布模型的整个生命周期。
图1-1 瀑布模型的整个生命周期
瀑布模型具有以下优点:
①为项目提供按阶段划分的检查瀑布模型的查点。
②当前一个阶段完成后,只需关注后续阶段。
③可在迭代模型中应用瀑布模型。
④它提供了一个模板,该模板使得分析、设计、编码、测试和支持的方法可以有一个共同的指导。
瀑布模型具有以下缺点:
①各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量。
②由于开发模型是线性的,用户只有等到整个过程的末期才能看到开发成果,从而增加了开发风险。
③通过过多的强制完成日期和里程碑来跟踪各个项目阶段。
④瀑布模型的突出缺点是无法适应用户需求的变化。
⑤早期的错误可能要等到开发后期的测试阶段才能被发现,进而带来严重的后果。
2.编译概念和工具
编译型语言:程序在执行之前需要一个专门的编译过程,把程序编译成机器语言文件,运行时不需要重新编译,直接使用编译结果即可运行。编译型语言需要依赖编译器,有程序执行效率高的优点,但跨平台性差。常见的编译型语言包括:C/C++、Pascal/Object Pascal(Delphi)、Golang。编译型语言的典型特征就是它们可以编译后生成.exe文件,之后无须再次编译,直接运行.exe文件即可。
解释型语言:程序在运行时才编译成机器语言,每执行一次都需要编译一次,因此执行效率比较低。在运行程序的时候才编译,有一个专门的解释器去进行编译,每个语句都是执行的时候才进行编译。解释型语言需要依赖解释器,有跨平台性好的优点,但执行效率比较低。常见的解释型语言有Java、C#、PHP、JavaScript、VBScript、Perl、Python、Ruby、MATLAB等。
3.基本程序调试知识和技巧
在软件开发的过程中,编写的代码并不总是按照预期行事。有时它也会执行一些完全不同的操作,发生这种情况时,使用调试工具或调试程序能让用户更轻松且更高效地找出问题所在。
正常运行应用时,仅在代码运行后才能发现错误和不正确的结果。程序也可能会意外终止而不告知用户原因。
在调试程序(也称为“调试模式”)中运行应用,这意味着调试程序会主动监视程序运行时发生的所有事情。此外,允许在任何时候暂停应用以检查其状态,然后逐行单步调试代码以查看应用运行的每个细节。
在Visual Studio中,通过使用调试工具栏中的F5(或“调试”→“开始调试”按钮或“开始调试”按钮)进入调试模式。如果发生异常,Visual Studio的异常帮助程序会找到发生异常的确切位置,并提供其他有用信息。
如果未收到异常,则在代码中查找可能出现问题的位置。可在此处结合使用断点和调试器,这样便有机会更仔细地检查代码。断点是可靠调试的最基本和最重要的功能。断点指示Visual Studio应在何处暂停正在运行的代码,以查看变量的值或内存的行为或代码运行的顺序。
4.C#语言概述
C#是微软2000年推出的一种基于.NET框架的、面向对象的高级编程语言。微软希望用C#取代Java。微软给它制定了一份语言规范,提供了从开发、编译、部署到执行的完整的服务,每隔一段时间会发布一份最新的规范,添加一些新的语言特性。
C#和Java类似,会编译成中间语言CIL(Common Intermediate Language,也叫MSIL)。CIL也是一种高级语言,而运行CIL的虚拟机叫CLR(Common Language Runtime)。通常我们把C#、CIL、CLR,再加上微软提供的一套基础类库称为.Net Framework。
以下为C#语言的基本语法规则及用法。
(1)C#数据类型。
在C#语言中,有以下几种数据类型:
● 值类型;
● 引用类型;
● 指针类型。
(2)C#变量。
变量是一个供程序操作的存储区的名字。在C#语言中,每个变量都有一个特定的类型,类型决定了变量的内存大小和布局。范围内的值可以存储在内存中,可以对变量进行一系列操作。表1-2中列出了C#语言基本变量类型。
表1-2 C#语言基本变量类型
有效的变量定义如下:
(3)C#运算符。
运算符是告诉编译器执行特定的数学或逻辑操作的一种符号。C#语言提供了丰富的内置运算符,包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符等。表1-3中罗列了C#语言支持的所有算术运算符。这里假设变量A的值为5,变量B的值为10。
表1-3 C#语言支持的所有算术运算符
表1-4中罗列了C#语言支持的所有关系运算符。假设变量A的值为5,变量B的值为10。表1-5中罗列了C#语言支持的所有赋值运算符。表1-6中罗列了C#语言支持的其他重要的运算符,包括sizeof()、typeof()和?。
表1-4 C#语言支持的所有关系运算符
表1-5 C#语言支持的所有赋值运算符
续表
表1-6 C#语言支持的其他重要的运算符
(4)C#判断结构。
判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。图1-2所示为C#语言中典型的判断结构的一般形式。
图1-2 C#语言中典型的判断结构的一般形式
表1-7中罗列了C#语言提供的判断语句类型。
表1-7 C#语言提供的判断语句类型
(5)C#循环语句。
有时可能需要多次执行同一代码块。一般情况下,语句是顺序执行的:函数中的第一个语句先执行,接着是第二个语句,以此类推。C#语言提供了允许更为复杂的执行路径的多种控制结构。循环语句允许我们多次执行一个语句或语句组,图1-3所示为C#语言中循环语句的一般形式。
图1-3 C#语言中循环语句的一般形式
表1-8中罗列了C#语言提供的循环类型。
表1-8 C#语言提供的循环类型
续表
通过循环控制语句可以更改执行的正常序列。当执行离开一个范围时,所有在该范围中创建的自动对象都会被销毁。表1-9中罗列了C#语言提供的控制语句。
表1-9 C#语言提供的控制语句
5.C#开发环境及工具
Microsoft Visual Studio(视觉工作室,简称VS或MSVS)是微软公司推出的开发工具包系列产品。Microsoft Visual Studio是一个基本完整的开发工具集,其中包含了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等。所写的目标代码适用于微软支持的所有平台,包括Microsoft Windows、Windows Phone、Windows CE、.NET Framework、.NET Compact Framework和Microsoft Silverlight。
而Visual Studio.NET是用于快速生成企业级ASP.NET Web应用程序和高性能桌面应用程序的工具。Microsoft Visual Studio包含基于组件的开发工具(如Visual C#、Visual J#、Visual Basic和Visual C++),以及许多用于简化基于小组的解决方案的设计、开发和部署的其他技术。Microsoft Visual Studio开发工具的图标如图1-4所示。
图1-4 Microsoft Visual Studio开发工具的图标
四、任务实施
1.C#程序开发环境的搭建与配置
步骤1:进入微软公司官网下载Visual Studio 2019,单击“社区”下方的“免费下载”按钮,如图1-5所示。
图1-5 Visual Studio 2019下载页面
步骤2:下载完成后打开Visual Studio 2019,标题为“Visual Studio Installer”,单击“继续”按钮,如图1-6所示。
图1-6 安装Visual Studio Installer
步骤3:Visual Studio Installer下载与安装界面如图1-7所示。
图1-7 Visual Studio Installer下载与安装界面
步骤4:安装完成后,在自动弹出的界面中选择“.NET桌面开发”选项,位置可按需求更改,单击“安装”按钮,如图1-8所示。
图1-8 Visual studio Installer安装配置界面
步骤5:等待安装完成。
步骤6:运行Visual Studio 2019,跳过登录步骤(若有微软账户也可以登录)。Visual Studio登录界面如图1-9所示。
图1-9 Visual Studio登录界面
步骤7:配置开发设置,选择“Visual C#”选项,单击“启动Visual Studio”按钮进入项目创建界面,如图1-10所示。
图1-10 Visual Studio初次启动配置
步骤8:Visual Studio 2019项目创建界面如图1-11所示,至此,C#程序开发环境已搭建并配置完成。
图1-11 Visual Studio 2019项目创建界面
2.设计一个简单的C#程序
步骤1:在项目创建界面选择“创建新项目”选项,如图1-12所示。
图1-12 创建新项目
步骤2:在第一个下拉列表框中选择C#语言,然后选择“控制台应用程序”选项,如图1-13所示,单击“下一步”按钮。
图1-13 选择C#控制台应用程序
步骤3:将项目命名为“HelloWorldApplication”,并设置存储位置,单击“下一步”按钮,如图1-14所示。
图1-14 为C#项目命名
步骤4:目标框架按照默认设置即可,单击“创建”按钮,如图1-15所示。
图1-15 设置C#控制台应用程序其他信息
步骤5:进入工作台,此处有默认代码。
C#程序主要包括以下部分:
● 命名空间声明(Namespace Declaration);
● 一个class;
● class方法;
● class属性;
● 一个Main方法;
● 语句(Statements)&表达式(Expressions);
● 注释。
让我们看一个可以打印出“Hello World!”的C#程序的初始代码,如图1-16所示。
图1-16 工作台默认Hello World程序代码
程序代码各个部分说明如下:
● 程序的第一行using System;中,using关键字用于在程序中包含System命名空间。一个程序中一般有多个using语句。
● 程序的第二行是namespace声明。一个namespace是一系列的类。HelloWorld Application命名空间中包含了HelloWorld类。
● 程序的第四行是class声明。HelloWorld类中包含了程序使用的数据和方法声明。类中一般包含多个方法。方法定义了类的行为。在这里,HelloWorld类只有一个Main方法。
● 程序的第六行定义了Main方法,是所有C#程序的入口点。Main方法说明当执行时类将做什么动作。
● Main方法通过语句Console.WriteLine("Hello World!");指定了它的行为。WriteLine是一个定义在System命名空间中的Console类的一个方法。执行该语句会在屏幕上显示消息“Hello World!”。
● 最后针对VS.NET用户的Console.ReadKey(),使程序等待一个按键的动作,防止程序在Visual Studio.NET启动时快速运行并关闭。
与Java程序不同的是,文件名可以不同于类的名称。以下几点需要注意:
● C#语言是大小写敏感的。
● 所有的语句和表达式必须以分号(;)结尾。
● 程序的执行从Main方法开始。
步骤6:尝试添加代码,输出文字“编写一个简单的C#程序。”如图1-17所示。
图1-17 添加“编写一个简单的C#程序。”文字输出代码
3.编译和运行C#程序
步骤1:单击位于工具栏中间的三角按钮运行程序,如图1-18所示。
图1-18 单击三角按钮运行程序
步骤2:程序运行界面如图1-19所示,单击键盘中的任意键退出该界面。
图1-19 程序运行界面
4.为C#程序添加注释
进行C#程序编码的时候,常常涉及代码注释,常见的注释包括以下两类。
(1)单行注释。该类注释格式为://注释语句。
示例程序如下:
程序运行结果如图1-20所示。
图1-20 单行注释的程序运行结果
语句被“//”注释后,不再输出。
(2)多行注释。该类注释格式为:/*注释语句...*/。
在代码中添加多行“Hello World!”并注释,代码如下:
程序运行结果如图1-21所示。
图1-21 多行注释的程序运行结果
语句被/*注释语句...*/注释后,不再输出。
(3)为代码添加注释。
示例程序如下:
程序运行结果如图1-22所示。
图1-22 添加代码注释后的程序运行结果
因为被“//”或“/*注释语句...*/”注释后的内容,编译器将不再对其进行解析,所以我们常用其来做代码的注释,方便用户阅读与理解代码,也可用于程序测试。
5.C#程序的调试
步骤1:创建一个新项目,并将其命名为“Console Application”,然后输入如下代码,如图1-23所示。
图1-23 创建新项目并输入代码
步骤2:按F5键,单击调试工具栏中的“开始调试”按钮(或选择“调试”→“开始调试”命令)调试程序,如图1-24所示。
图1-24 单击“开始调试”按钮
通过F5键启动应用时,调试器会附加到应用进程,但现在我们还未执行任何特殊操作来检查代码。因此应用只会加载,控制台输出结果如图1-25所示。
图1-25 控制台输出结果
步骤3:为代码设置断点。
在Main()函数的for循环中,通过单击以下代码行的左边距来设置断点:
设置断点的位置会出现一个红色圆圈,如图1-26所示。
图1-26 设置断点后的效果
断点是可靠调试的最基本和最重要的功能之一。断点用于指示Microsoft Visual Studio应在哪个位置挂起运行代码,以便查看变量的值或内存的行为,或者确定代码的分支是否运行。
按F5键或单击“开始调试”按钮,应用随即启动,调试器将运行到设置断点的代码行,如图1-27所示。
图1-27 开始调试
黄色箭头表示调试器暂停执行的语句,它还在同一点上暂停应用运行(此语句尚未执行)。
如果应用尚未运行,按F5键会启动调试器并在第一个断点处停止应用运行。否则,按F5键将继续运行应用至下一个断点。
在要详细检查代码行或代码段时,断点功能非常有用。
步骤4:使用数据提示浏览代码和检查数据。
在name+=letters[i]语句上暂停应用运行时,将鼠标悬停在letters变量上,会看到其默认值为数组中第一个元素的值char[10]。
允许检查变量的功能是调试器提供的最实用的功能之一,并且由不同的方法来执行此操作。通常,当尝试调试程序时,我们会试图找出变量是否存储了我们期望它们在特定时间具有的值。
展开letters变量查看其属性,其中包括变量包含的所有元素,如图1-28所示。
图1-28 查看letters变量的属性
将鼠标悬停在name变量上,会看到其当前值为空字符串,如图1-29所示。
图1-29 查看name变量的值
步骤5:常用的调试命令包括逐语句、逐过程和跳出。
逐语句:可以按F11键实现,用于逐条语句运行。
逐过程:可以按F10键实现。逐过程是指可以将方法作为一个整体去执行,不会跳进方法中执行。
跳出:可以按Shift+F11组合键实现。跳出是指退出程序的调试状态,并结束整个程序的运行。
按F10键将使调试器前进到下一条语句运行,如图1-30所示。
图1-30 按F10键运行下一条语句
多按几次F10键(或选择“调试”→“单步跳过”命令),通过for循环执行多次循环访问,再次在断点处暂停,每次都将鼠标悬停在name变量上以检查其值。
变量的值随for循环的迭代而更改,显示的值依次为f、fr、fre,依此类推。要在此方案中更快地前进到循环,可以按F5键(或选择“调试器”→“继续”命令),此操作会使调试器前进到断点,而不是下一条语句。
通常情况下,在调试程序时,需要快速检查变量的属性值,以查看它们是否存储了我们期望它们在特定时间具有的值,可根据数据提示执行此操作。