作为本书的开篇,首先介绍ASP.NET Web开发最基础的知识,具体包括如下: Web开发的一些常见的基础概念;
Visual Studio 2005:本书将利用其作为开发环境,介绍ASP.NET开发技术; C#语法基础:C#是微软为.NET量身定做的开发语言,与C和C++非常相似。 本章的内容主要是考虑入门读者的需要,而对于掌握本章内容的读者,则可直接跳过本章。
0.1 基础概念
本节首先介绍Web开发中的一些常见术语,包括网页的概念(Web Server、URL、Client、Browser)、常见的网页开发技术(HTML、CGI、ASP/ASP.NET、PHP、JSP),以及Web开发相关的技术(Java、JavaScript、CSS、Flash)等。
0.1.1 什么是网页
网页(Web Page)实际是一个文件,存放在世界某个角落的的某一台计算机中,而这台计算机必须是与互联网相连的,称为Web服务器(Web Server)。网页经由网址(URL)来识别与存取,当在浏览器输入网址后,经过一段复杂而又快速的程序,网页文件会被传送到使用者的计算机(客户端),然后再通过浏览器(Wen Browser)解释网页的内容,再展示到用户的面前,如图0.1所示。
(2)Web服务器定位网页文件(1)用户请求Web页面(3)Web服务器处理指令,生成HTMLWeb服务器(5)浏览器显示HTML(4)将HTML文档返回浏览器浏览器终端
图0.1 Web页面工作机制
网页的两个最基本的元素是文字与图片。可以简单的理解为:文字,就是网页的内容;图片,就是网页的美观。除此之外,网页的元素还包括动画、音乐、程序等等。在Web应用中,存在两种页面:静态页面和动态页面,下面分别简单介绍。
1.静态网页
静态网页:是单向服务,如常见的新闻网页等。在这种服务中,Web页面只能向用户显示预先编辑好的信息,用户只能“看”而不能有其他行为,以常见的HTML网页(文件后缀为.htm或.html)为主。
2.动态网页
动态网页:与静态网页相对应,动态网页提供的服务是双向的,它既可以向用户传递信息,也能够接受用户反馈,并根据反馈做出响应,常见的网页类型如.php、.asp、.aspx等。动态网页的应用非常广泛,如聊天室、论坛、电子商务应用等。常见的静态网页和动态网页如图0.2所示。
静态页面.htm.html动态页面.php.jsp.asp.aspx…用户图0.2 Web应用中的两种服务页面类型
0.1.2 网页开发技术
通常看到的网页,都是以htm或html后缀结尾的文件,简称HTML文件。除此之外,还有例如以CGI、ASP、PHP、JSP甚至其他更多为后缀的网页,不同的后缀,代表了不同类型的网页类型,也代表了不同的网页开发技术。下面介绍几种常见的网页类型。
1.HTML
HTML(Hyper Text Markup Language,超文本标记语言)利用标记(tag)来描述网页的字体、大小、颜色及页面布局的语言,使用任何的文本编辑器都可以对它进行编辑,HTML与VB、C++等编程语言有着本质上的区别。
对于网页制作初学者来说,理解HTML的工作原理是必要的,但也无须仔细地了解到每一个标记的作用,因为已经有了很好的所见即所得的网页编辑软件来快速地生成HTML代码,例如Dreamweaver和Frontpage,再也无须象早期的网页制作人员一样,一行一行地编写HTML代码。
2.CGI
CGI(Common Gateway Interface,公共网关接口),是一种编程标准,规定了Web服务器调用其他可执行程序(CGI程序)的接口协议标准。CGI程式通过读取使用者的输入请求从而产生HTML网页。CGI程序可以用任何程序设计语言编写,如Shell、Perl、C、Java等,其中最为流行的是Prel。CGI程序通常用于查询、搜索、或其他的一些交互式的应用。
3.ASP
ASP(Active Server Pages,动态服务器主页),是一种应用程序环境,可以利用VBscript或JavaScript脚本来设计,主要用于网络数据库的查询与管理。其工作原理:是当浏览者发出浏览请求的时候,服务器会自动将ASP的程序码,解释为标准HTML格式的网页内容,再将这些网页内容发送到浏览器上显示出来。从这个角度上,也可以将ASP理解为一种特殊的CGI。
利用ASP生成的网页,与HTML相比具有更大的灵活性。只要结构合理,一个ASP页面就可以取代成千上万个网页。尽管ASP在工作效率方面较之一些新技术要差,优点包括简单、直观、易学。
4.PHP
PHP(Hypertext Preprocessor,超文本预处理器),其优势在于其运行效率比一般的CGI程序要高,而且完全免费,任何人都可以从PHP官方站点(http://www.php.net)自由下载。PHP可跨平台运行,在大多数Unix平台,GUN/Linux和微软Windows平台上均可运行。
5.JSP
JSP与ASP非常相似,不同之处在于:
(1)ASP的编程语言是VBScript之类的脚本语言,而JSP使用的是Java。 (2)两种语言引擎用完全不同的方式处理页面中嵌入的程序代码。在ASP下,VBScript
代码被ASP引擎解释执行;在JSP下,代码被编译成Servlet并由Java虚拟机执行。
6.ASP.NET
ASP.NET的前身ASP以其简单的语法、嵌入HTML方式等,在动态Web技术领域取得了成功,成为Windows平台上的霸主。后来又出现了PHP、JSP等技术,两者在执行效率、安全性等特性上均优于ASP,并可免费使用,跨平台移植。
PHP、JSP等技术的出现,使ASP的统治地位受到了挑战,它们占有了ASP大量的市场。在这种情况下,在ASP的基础之上,微软于2000年11月发布了ASP.NET,并与2005年正式发布了功能更为强大、使用更为简单的ASP.NET2.0。对于Web开发人员而言,ASP.NET2.0是MicrosoftWeb开发史上的一个重要的里程碑。
说明:在下一章中,将详细介绍ASP.NET有关内容。
0.1.3 Web开发相关技术
本节将介绍最重要的Web开发相关技术,这些技术与ASP.NET没有直接的关系,但掌握这些概念将帮助读者在学习时触类旁通。下面,就简单介绍一些对最常见的Web开发相关技术。
1.Java
Java是由Sun公司开发而成的一种编程语言,利用Jave写成的小程序叫做JavaApplet。使用它可在各式各样不同种机器、不同种操作平台的网络环境中开发软件。而且,不论使用的是哪一种浏览器,哪一种计算机,哪一种操作系统,只要浏览器上面注明了“支持Java”,就可以看到生动的页面。
当初Java面世的时候,曾经轰动一时,被认为将会成为Internet应用的主要开发语言。但时至今日,Java的市场占有率已大不如前,原因是Java也有着其致命的弱点,就是在客户端的编译运行的速度慢,资源消耗大。现在Java多用于服务器端、及一些复杂的客户端程序的编写。
2.JavaScript
JavaScript是一种脚本语言,通过嵌入或整合在标准HTML中实现,也就是说JavaScript的程序是直接加入在HTML文档里,当浏览器读取到HTML文件中JavaScript的程序,就立即解释并执行有关的操作,无须编译器,其运行速度比JavaApplet要快得多。
JavaScript编写容易,不需要有很深的编程经验。现在,JavaScript已经成为制作动态网页必不可少的元素,读者经常在网页上看到的动态按钮、滚动字幕,就大多数都是使用JavaScript技术制作的。
说明:JavaScript和Java有关系吗?两者没有任何关系。Java是Sun公司的产品,而JavaScript是Netscape公司推出的,早期称之为LiveScript,后来为了利用Java的功能同时借用它的流行性,把它改名为JavaScript。
3.CSS
CSS(Casading Style Sheets,层叠样式表),与HTML一样也是一种标记语言,甚至很多属性都是来源于HTML。利用CSS技术,可以有效地对页面的布局、字体、颜色、背景和其他效果实现更加精确的控制。要对相应的代码做一些简单的修改,就可以改变同一页面的不同部分,或者页数不同的网页的外观和格式。
4.Flash
Flash是Macromedia公司出品的一个适量动画制作软件,用其做出来的动画就叫Flash动画,其特点包括:
动画具有很强的交互性,甚至可以完全使用Flash来制作一个网站;
采用“准”流(Stream)式的设计,可以一边下载动画文件一边欣赏动画;
由于它是基于矢量的图形系统,可大大地减少文件的数据存储量。同时,可以做到
真正的无限放大,无论用户的浏览器使用多大的窗口,图像始终可以完全显示,并且不会降低画面质量。
如果读者看过并使用了Flash技术的网站,肯定会被其绚丽的效果所吸引。同时,Flash也有其弊端,就是维护更新不方便,不适宜用于一些更新频繁、信息量大的网站。
0.2 搭建开发环境
前面介绍了一些Web开发中经常见到的基础概念,下面言归正传,开始介绍ASP.NET开发技术。“工欲善其事,必先利其器”,本节就将介绍如何搭建ASP.NET开发环境,并带领读者,完成第一个最简单的ASP.NET动态页面:“HelloWorld”。
0.2.1 安装Visual Studio 2005
VS.NET 2005的安装非常简单,安装之前首先要检查一下自己的软硬件环境是否能达到所要求的运行环境,以专业版为例,微软给出的建议配置如下: 处理器:600 MHz 或更快配置 操作系统:VS.NET 2005 Professional Edition 可以被安装在以下的操作系统中:
Microsoft Windows 2000 + Service Pack 4
Microsoft Windows XP + Service Pack 2
Microsoft Windows XP Professional x64 Edition Microsoft Windows Server 2003 + Service Pack 1 Microsoft Windows Server 2003,x64 Editions Microsoft Windows Server 2003 R2
Microsoft Windows Server 2003 R2,x64 Editions Microsoft Windows Vista 内存:192 MB RAM 或更大配置
硬盘空间:至少2 GB 可用硬盘空间 光盘驱动器:DVD-ROM 驱动器
显示器:1024x768 + 256色或更高分辨率和颜色数的显示器 输入设备:键盘、鼠标或其他兼容指针设备
将安装程序放入光驱,出现如图0.3所示的安装界面,当系统中没有安装VS.NET时,下面的两项是灰色的,表明此时只能安装VS.NET2005。
图0.3 Visual Studio.NET2005安装界面
单击“安装Visual Studio 2005”选项,根据安装程序提供的向导进行安装,因为安装
过程较简单,只需根据提示安装即可,因此此处不再赘述。
0.2.2 Visual Studio 2005简介
本书将主要使用VS.NET 2005作为开发环境,所以首先认识一下这个IDE工具。VS.NET是一个非常复杂、庞大的产品,秉承了微软开发环境的一贯风格,使用非常简单。在启动VS.NET时,主窗口会出现一系列窗口,以及历史解决方案列表,如图0.4所示。
图0.4 VS.NET 2005启动界面
下面仅介绍一下VS.NET最基本的一些功能:
(1)把鼠标放在隐藏的窗口上,便会自动弹出这些窗口。
(2)“工具箱”窗口显示常用的窗体控件,通过简单的拖拽操作,便可以快速开发图形化界面工程。
(3)“解决方案资源管理器”窗口显示当前解决方案的信息(解决方案即一个或多个工程及其配置的综合),窗口中可以查看解决方案中工程的各种视图,例如其中的文件等。
(4)“属性”窗口显示工程内容更详细的信息,可以对工程中的单个控件或其他对象进行配置。例如,可以使用属性窗口改变一个按钮的外观、大小等。
(5)“任务列表”窗口和“输出”窗口显示编译工程时的信息,以及开发环境已经完成的任务。
此处,仅仅认识一下VS.NET 2005,对于其较为详细的使用并不作详细介绍。
0.2.3 实现第一个ASP.NET程序
【本节示例参考:\\示例代码\\C01\\HelloWorld】
本节来使用C#实现的一个最简单的Web应用HelloWorld,本例步骤如下: (1)启动VS.NET;
(2)单击菜单,执行命令【文件】【新建】【网站】;
(3)弹出“新建网站”对话框。选择“ASP.NET网站”,在下侧的“位置”下拉框中选择“文件系统”,然后输入“D:\\示例代码\\C00\\HelloWorld”,“语言”下拉框选择“C#”,然后单击“确定”按钮,如图0.5所示。
(4)查看“解决方案资源管理器”窗口,应该如图0.6所示。
图0.5 新建ASP.NET网站 图0.6 HelloWorld的资源管理器
在文件“Default.aspx”上单击右键,选择“重命名”,将其改名为“HelloWorld.aspx”; (5)查看主窗口,里面有一个自动生成aspx页面,将代码
改为
在页面显示时,页面的标题将为“Hello World,ASPNET.”;
(6)单击主窗口左下方的“设计”标签,然后单击主窗口左侧的“工具箱”隐藏窗口,默认出现一些标准Web控件。双击“Label”控件,或者单击后按住左键将其托拽至主窗口的窗体中,并修改其属性:
ID:lblDisplay Text:空
BackColor:Silver 双击“Button”控件,或者单击后按住左键将其拖拽至主窗口的窗体中,并修改其属性: ID:btnShow Text:“显示”
最后效果如图0.7所示。
图0.7 添加Label和Button后的aspx页面
(7)双击“显示”按钮,将进入代码窗口(通过主窗口上侧的标签可以在代码窗口和窗体窗口间进行切换),可以看到VS.NET已经自动生成了很多代码,在此不必关心。进入代码窗口后光标自动位于方法“btnShow_Click()”内部(即单击“显示”按钮,会触发这个方法),在光标处添加如下代码:
this.lblDisplay.Text=\"Hello World, ASP.NET.\";
(8)在“资源管理器”中,右击“HelloWorld.aspx”页面,弹出快捷菜单,选择执行“设为起始页”命令。
(10)使用快捷键“CTRL+F5”,或者在菜单中执行【调试】【开始执行】命令,启动程序后,结果如图0.8所示,单击“显示”按钮,在标签中就会出现结果。
图0.8 HelloWorld运行结果
(9)查看工程文件:在目录“D:\\示例代码\\C00”下,将会发现工程文件夹“HelloWorld”。其中:
.aspx:页面文件; .cs:代码文件。
至此,第一个ASP.NET Web应用就完成了。
关闭工程后,要想重新打开,只需要在VS.NET 2005中执行【文件】【打开】【网站】命令,然后选择网站所在的文件夹即可。
0.3 C# 2.0语言基础
虽然.NET可以支持多种开发语言,但只有C#是为.NET Framework量身定做,它拥有
所有.NET Framework提供的优点,如资源回收,内存自动管理等,能够最完美的体现了.NET的功能。
0.3.1 简介
首先,来了解一下C#的诞生。以前,在选择开发语言时,许多程序员面临着两难的抉择:一方面,C和C++提供了强大的功能、高度的灵活性,以及完整的底层控制能力。但是,其缺点在于开发周期较长,另外学习较困难。另一方面,许多开发效率更高的语言,如Visual Basic,在功能方面又具有局限性。
针对这个问题,微软发布了称之为C#(C Sharp)的编程语言,它是为.NET平台量身定做的开发语言,采用面向对象的思想,支持.NET最丰富的基本类库资源。C#提供快捷的开发方式,又没有丢掉C和C++强大的控制能力。
C#与C和C++非常相似,C和C++程序员能够很快掌握C#。C#综合了目前所有语言特点的基础上,如图0.9所示。
196019651970197519801986199019952000FORTRANCoblo AlgolAlgol 60LispSimulaSimula 67BasicPLAPascalCFORTRAN 77Module 2AdaC++SmallTalkEiffelFORTRAN 90Visual BasicFORTRAN 95OberonJavaC#
图0.9 C#家谱
那么,与其他语言相比,C#有哪些优点呢?此处,将C#与其他常用开发语言做一个简单的对比,如表0.1所示。
表0.1 C#与其他开发语言的比较
比较语言 C#优点 C#不足 VC++ 效率稍低 在安全代码中禁止使用指针
不适合设备驱动程序和操作系统内核实删除了复杂的宏
现 在引用变量之前必须显示声明,并初始化
删除了全局函数,彻底化面向对象思想 支持快速开发图形化用户界面 开发周期短,更容易维护 适合商业应用和Web开发
C++ Builder 可以于.NET语言编写的代码无缝交互 - Java 语法更加强大 平台独立性稍差
可以于.NET语言编写的代码无缝交互 .NET基类库更加标准化
VB6 具有广泛的使用者 可以于.NET语言编写的代码无缝交互
Microsoft的继续支持 允许使用.NET框架基类库更多功能
更高的面向对象特性 更加简洁
VB.NET 可以完成指针功能 -
Microsoft将采用C#进行开发 两者非常类似
Delphi 允许与其他语言所编写的代码交互 -
语法简洁
容易实现平台独立性
0.3.2 数据类型
C#支持Common Type System(CTS),其数据类型包括基本类型,如int、char、float等,也包括比较复杂的类型,如string、decimal等。作为完全的面向对象语言,C#中的所有数据类型是一个真正的类,具有格式化、系列化,以及类型转换等方法。根据在内存中存储位置的不同,C#中的数据类型可分为两类: 值类型:该类型的数据长度固定,存放于栈内,包括整数、浮点数、字符以及布尔
类型等; 引用类型:该类型的数据长度可变,存放于堆内,包括数组、集合等对象。
下面逐一介绍。
1.整数类型
C#支持8种整数类型,具体含义如表0.2所示。
表0.2 整数类型
名称 CTS类型 说明 范围
7sbyte System.SByte 8位有符号整数 -128~127(-2~27-1) short System.Int16 16位有符号整数 -32 768~32 767(-215~215-1) int System.Int32 32位有符号整数 -231~231-1 long System.Int64 64位有符号整数 -263~263-1 byte System.Byte 8位无符号整数 0~255(0~28-1) ushort System.Uint16 16位无符号整数 0~65535(0~216-1) uint System.Uint32 32位无符号整数 0~232-1 ulong System.Uint64 64位无符号整数 0~264-1
2.浮点数
C#支持3种浮点数类型,如表0.3所示。
表0.3 浮点数类型
名称 CTS类型 说明 float System.Single 32位单精度浮点数 double System.Double 64位双精度浮点数 decimal System.Decimal 128位双精度浮点数
+-+-+-
范围
1.5×10-45~+-3.4×1038 5.0×10-324~+-1.7×10308 +1.0×10-28~-7.9×1028 其中,decimal类型用于财务计算,表示货币值。另外也可以在其他需要高精度的地方使用。
3.布尔型
C#的布尔型是bool,其取值包括true和false,如表0.4所示。
表0.4 布尔型
名称 CTS类型 值域 bool System.Boolean true/false 在C#中,bool类型的数据和整数不能互相转换,即如果声明变量为bool型,则就只能
对其赋值为true或false,而不能使用1或者0,这与C和C++不同。
4.字符型
C#的字符型可以保存单个字符的值,如表0.5所示。
表0.5 字符型
名称 CTS类型 值域 char System.Char 表示一个16位的Unicode字符
在C#中,Char类型的值需要放在单引号中,例如‘A’。另外,对于一些特殊的字符,
例如单引号,可以通过转义字符来表示。C#中的转义字符如表0.6所示。
表0.6 C#中的转义字符
转义字符 \\' \\\" \\\\ \\0 \\a \\b \\f \\n \\r \ \\v
单引号 双引号 反斜杠 空字符 警告 退格符 换页符 换行符 回车符 水平制表符 垂直制表符
意义
5.结构
除去上面介绍的简单值类型之外,用户还可以根据它们定义复合值类型。常用的复合值类型包括结构和枚举,首先来看结构。
一个结构(struct)是包含多个基本类型或复合类型的统一体,在C#中可以使用struct关键字创建结构,例如,一个学生结构如下:
1. ///
4. public struct Student 5. { 6. public long Sid; //学号 7. public string SName; //姓名 8. public double Score; //成绩 9. }
在这里使用了结构,而不是类,这是因为与类相比,结构有如下的优点: 结构占用栈内存,对其操作的效率要比类高; 结构在使用完后能够自动释放内存分配; 结构很容易复制,只需要使用等号把一个结构赋值给另一个即可,对于类,则不能
这样操作,例如:
1. Student s1=new Student();
2. Student s2; 3.
4. s1.Sid=1;
5. s1.SName=\"张三\"; 6. s1.Score=80; 7.
8. s2=s1;
6.枚举
枚举(enum)其实是一个整数类型,用于定义一组基本整数数据,并可以给每个整数指定一个便于记忆的名字。例如,一个星期枚举类型如下:
1. ///
4. public enum enumWeek 5. {
6. Sunday=0, 7. Monday=1, 8. Thuesday=2, 9. Wedensday=3, 10. Thursday=4, 11. Friday=5, 12. Saturday=6 13. }
建立这个星期枚举之后,便可以使用名称来表示特定的整数值,例如,Week.Monday即代表整数1。下面是一个使用的Week枚举的示例:
1. int i=0; 2. switch(i) 3. { 4. case (int) enumWeek.Sunday: //返回0 5. Console.WriteLine(\"菲菲的生日\"); 6. break; 7. case (int) enumWeek.Monday: //返回1 8. //... 9. }
从长远来看,在编程中创建枚举可以节省大量时间,因此要适当地使用枚举。 7.数组
C#把数组看作一个带有方法和属性的对象,并存储在堆内存中。同C风格类似,声明数组时,要在变量类型后面加一组方括号。例如,下面语句定义一个整数数组:
int[] nVar;
这里只是定义了数组变量nVar,并没有初始化,即并没有为其开辟内存空间。若要初始化特定大小的数组,需要使用new关键字:
int[] nVar=new int[100];
同C语言一样,C#使用下标来引用数组元素,其下标从0开始。另外,C#还可以使用
数组的实例来初始化数组,如:
int[] nVar={0,1,2,3};
这等价于
int[] nVar=new int[] {0,1,2,3};
数组作为一个对象,有自己的属性和方法,常用的属性包括: .Length:一维数组的长度。 .Rank:数组的维数。
常用的方法是.GetLength(int dimension),用来获取多维数组中指定维的长度。 在【第5章 数组和集合】中,将详细介绍集合和数组操作。
8.类、接口
类在C#和.NET Framework中是最基本的用户自定义类型。类也是是一种复合数据类型,包括属性和方法。接口用于实现一个类的定义,包括属性、方法的定义等,但没有具体的实现,也不能实例化接口。
在【第2章 命名空间、类和对象】中,将详细介绍类的概念。
0.3.3 变量和常量
作为最基本的功能,程序需要操作数据来完成运算,当需要保存数据的值或计算结果时,便需要使用变量。
举一个简单的例子来说明数据和变量的关系,假设某人身高是180cm,那么“180”便是数据,而“身高”是变量。可以说“身高增加1”,即对变量进行操作,而不会说“180增加1”,这时“身高”将改变为“181”。
1.命名变量
在C#中,使用变量的基本原则是:先定义,后使用。首先来看为变量命名的方法。C#中的变量命名规范为:
(1)必须以字母或下划线开头;
(2)只能由字母、数字、下划线组成,不能包含空格、标点符号、运算符,以及其他符号;
(3)不能与C#关键字同名,如class、new等。
需要注意的是,C#中的变量名可以以“@”作为前缀,这时就可以使用“@”+关键字作为变量名,如“@class”。但是,“@”本身并不是变量名的一部分,例如在本例中,真正的变量名仍然是“class”。
下面是一些合法的变量命名示例:
int i;
string error_message; char @new;
下面是一些不合法的变量命名示例:
int No.1; char 1_new; string static; //不能包含标点符号 //以数字开头 //与关键字同名
2.声明和使用变量
上面介绍了C#中的变量命名规范,下面来看如何声明和使用变量。变量的声明非常简单,只需要在数据类型后面加上变量名即可,如:
int i;
string s1,s2;
另外,还可以使用变量类型关键字,如“static”,来定义变量的类型。C#变量中的变量大体分为3种类型,它们有各自的特点,分别介绍如下:
(1)实例变量
不带有任何关键字声明的变量称为实例变量,如:int i。实例变量在其所在的方法调用结束后,其数据将会被清除掉,所占的内存空间也会被释放。
(2)静态变量
使用“static”关键字修饰的变量称为静态变量。如:
static int count=0
同实例变量相对,静态变量在函数调用结束后仍保留变量值,直到程序结束前一直存在。另外,静态变量不能在类的方法中定义,因为这没有任何意义。
静态变量的这种性质是很重要的。例如,在一个聊天室程序里,可以使用静态变量记录浏览者人数,在每一次新到用户或用户离开的时候,都应该保留目前浏览者人数。
(3)局部变量
局部变量是指在一个独立的代码块中声明的变量,它只在这个代码块中有效,一旦离开这个范围,将不再存在。
C#中没有全局变量,因为它是面向对象的语言。当然可以使用类来实现其功能。 声明变量并赋值后,就可以通过直接引用变量名来使用它,如:
s1=\"Hello World\";
Console.WriteLine(s1);
3.声明和使用常量
同变量一样,常量也用来存储数据。它们的区别在于,常量一旦初始化就不再发生变化,可以理解为符号化的常数。
使用常量可以使程序变得更加灵活易读,例如,可以用常量PI来代替3.1415926,一方面程序变得易读,另一方面,需要修改PI精度的时候,无需在每一处都修改,只需在代码中改变PI的初始值即可。
常量的声明和变量类似,需要指定其数据类型、常量名,以及初始值,并需要使用const关键字,例如:
[public] const double PI=3.1415;
其中,[public]关键字可选,并可用private、protected、internal或new代替。 声明变量并赋值后,就可以通过直接引用变量名来使用它,如:
double r=3.2;
====double area=PI*r*r; ====Console.WriteLine(area); ====
0.3.4 运算符
C#中的运算符是用来对变量、常量或数据进行计算的符号,它指挥计算机进行什么样的操作。
1.算数运算符
算术运算符(arithmetic operators)用来处理四则运算的符号,是最简单、也最常用的符号,尤其数字的处理几乎都会使用到算术运算符号。C#中的算数运算符如表0.7所示。
表0.7 C#的算数运算符
符号 示例 意义 + a+b 加法运算 - a-b 减法/取负运算 * a*b 乘法运算 / a/b 除法运算 % a%b 取余数 ++ a++ 累加 -- a-- 递减
2.字符串运算符
字符串运算符(string operator)只有一个,就是加号“+”。除了作为算术运算符之外,
它还可以将字符串连接起来,变成合并的新字符串。例如:
1. string s=\"Hello\"; 2. s=s+\World.\";
3. Console.WriteLine(s); //输出:Hello, World.
3.赋值运算符
赋值运算符(assignment operator)把其右边表达式的值赋给左边变量或常量。C#中的赋值运算符如表0.8所示。
表0.8 C#中的赋值运算符
符号 示例 意义 Ab 将右边的值连到左边 + a+b 将右边的值加到左边(数字或字符串都可) - a-b 将右边的值减到左边 * a*b 将左边的值乘以右边 / a/b 将左边的值除以右边 % a%b 将左边的值对右边取余数
使用上面的赋值运算符往往可以使代码更为简洁,而且更重要的是能够比先运算后再
赋值具有更高的执行效率。
4.逻辑运算符
逻辑运算符(logical operators)通常用来测试真假值。C#中的逻辑运算符如表0.9所示。
表0.9 C#中的逻辑运算符
符号 示例 为真的条件
< a a>b 当a的值大于b值时 < a a>b 当a的值大于或等于b值时 = = a==b 当a的值等于b值时 ! a!b 当a的值不等于b值时 && a&&b 当a为真并且b都为真时 || a||b 当a为真或者b都为真时 ! !a 当a为假时
5.位运算符
位运算符(bitwise operators)用于做一些快速的数字运算,共有6个,如表0.10所示。
表0.10 C#的位运算符
符号 示例 意义
& a&b 按位与运算 | a|b 按位或运算 ^ a^b 按位异或运算 =<< a<< 向左移位 =>> a>> 向右移位 =~ ~a 按位取反
==
=
6.其他运算符
除上面5种运算符之外,C#还包括一些特殊的运算符。其使用和意义参考如表0.11所示。
表0.11 C#的其他运算符
符号 示例 new new Class1(); typeof typeof(int); . Obj.method(); ? : (expr1)?(expr2) : (expr3);
意义
创建一个类的实例 获取数据类型说明
获取对象的方法或者属性 若expr1则expr2;否则expr3
7.运算符的优先级
运算符的优先级是指在表达式中哪一个运算符应该首先计算。算术中四则运算时“先乘除,后加减”便是运算符优先级的很好体现。
C#根据运算符的优先级确定表达式的求值顺序:优先级高的运算先做,优先级低的操作后做,相同优先级的操作从左到右依次做,同时用小括号控制运算顺序,任何在小括号内的运算最优先进行。如表0.12所示给出了C#操作符的优先级。
表0.12 运算符的优先级
级别
运算符
1 new、typeof、. 2 赋值运算符 3 ||, && 4 |, ^
5 & 6 +, -(加、减运算符) 7 /, *, % 8 <<, >> 9 ++, -- 10 +, - , (正、负号运算符)! ,~ 11 = =, !=, <> 12 <, <=, >, >= 13 ? :
0.3.5 流程控制
前面3节介绍了变量、常量和运算符,三者是构成每行C#语句的必要元素。在这一节,
将在另一个层次介绍如何控制一段代码的整体结构。
同其他高级语言类似,C#的程序结构除顺序结构外,主要有分支结构和循环结构,另外,C#还支持无条件跳转。
1.使用if语句实现分支
【本节示例参考:\\示例代码\\C00\\Example_If】
当程序需要在一个二叉路口做出选择时,需要用到if语句,控制在某条件下才执行某个功能,否则执行另一个功能。例如,当判断一个学生是否及格时,需视其成绩是否大于60做出决定,这时就可以利用if语句进行控制。if语句实现分支有3种类型:
若发生了某事则怎样处理
1. if (expression) 2. {
3. statement 4. }
若发生了某事则怎样处理,否则该如何解决
1. if (expression) 2. {
3. statement1 4. } 5. else 6. {
7. statement2 8. }
嵌套使用if…else进行多个条件的判断
1. if (expression1) 2. {
3. statement1
4. } 5. elseif (expression2) 6. {
7. statement2 8. } 9. else 10. {
11. statement3 12. }
其中的expression为判断条件,通常都是用逻辑运算符作为判断的条件。而statement为符合条件的执行区段程序。若程序只有一行,可以省略大括号。三者的使用示例如下。
代码0-1 if语句示例:Class1.cs
1. /// 3. ///
4. protected void Button1_Click(object sender, EventArgs e) 5. { 6.
7. //1 使用if语句
8. if (TextBoxInput.Text >= 60) 9. {
10. LabelResult.Text = \"及格\"; 11. } 12.
13. //2 使用if...else...语句 14. if (TextBoxInput.Text >= 60) 15. {
16. LabelResult.Text = \"及格\"; 17. 18. 19. 20.
} else {
LabelResult.Text = \"不及格\";
21. } 22.
23. //3 使用if...else if...else语句
24. if (Convert.ToInt32(TextBoxInput.Text) > 80) 25. {
26. LabelResult.Text = \"优秀\"; 27. 28. 29. 30.
} else if (Convert.ToInt32(TextBoxInput.Text) >= 60) {
LabelResult.Text = \"及格\";
31. } 32. else
33. {
34. LabelResult.Text = \"不及格\"; 35. } 36. }
示例分别使用了三种类型的if语句。其中在if...elseif…else类型中,本示例中只用了二层的if...elseif…else分支,用来判定分数是及格、优秀,还是不及格。
同【0.2.3】类似,建立一个新的网站Example_If。在页面Default.aspx中,添加页面元素用来输入分数和显示成绩,将可以看到如图0.11所示的运行结果。
图0.11 if...else if...else语句示例运行结果
说明:此处,因为示例非常简单、不再赘述示例中页面元素的定义等详细的实现步骤,
请读者根据随书光盘中附带的代码,执行实现。本章下面几个示例,均与此同。
使用嵌套if...else 分支时,太多层的分支容易引起混乱,如少写了大括号等,这时可以考虑使用switch语句实现分支。
2.使用switch语句实现分支
【本节示例参考:\\示例代码\\C00\\Example_Switch】
当程序面临多叉路口时,就可以使用swtich语句进行分支。例如,当对一个学生评估时,可能会有多个选择:60以下、60~60、70~79、80~89、90~100,需要视其分数给予不同评语,这时就可以使用swtich语句进行分支。switch开关语句语法结构为:
1. switch(variable) 2. {
3. case value1: 4. statement1 5. break; 6. case value2: 7. statement2 8. break; 9. … 10. default: 11. statement 12. break; 13. }
其中,每个可能的分支都对应着一个case语句。switch判断被检查的变量variable符合哪一个case语句中的value,就执行匹配成功的分支语句。
如果case分支中没有break语句,那么即使匹配了此分支,程序也将继续进入下一个
case分支,直到遇到break关键字为止。若没有任何分支满足条件,程序最后将进入default分支。下面的示例使用switch根据星期几判断应该做什么:
代码0-2 switch语句示例:Class1.cs
1. /// 3. ///
4. protected void Button1_Click(object sender, EventArgs e) 5. {
6. //使用switch 7. 8. 9. 10.
switch (Convert.ToInt32(TextBoxInput.Text)) {
case (int)enumWeek.Monday: LabelResult.Text = \"客户提案\";
11. break; 12. case (int)enumWeek.Thuesday: 13. LabelResult.Text = \"菲菲的生日\"; 14. break; 15. case (int)enumWeek.Wedensday: 16. LabelResult.Text = \"我要shopping\"; 17. break; 18. case (int)enumWeek.Thursday: 19. LabelResult.Text = \"去健身房\"; 20. break; 21. case (int)enumWeek.Friday: 22. LabelResult.Text = \"向Boss汇报工作\"; 23. break; 24. case (int)enumWeek.Saturday: 25. LabelResult.Text = \"我要吃!\"; 26. break; 27. case (int)enumWeek.Sunday: 28. LabelResult.Text = \"周末狂欢\"; 29. break; 30. default: 31. break; 32. } 33. }
上面的示例在6种选择中,根据今天是星期几(变量nWeekday的值)决定要做什么,其中使用了0.3.2节给出的星期枚举。switch语句示例运行结果如图0.12所示。
图0.12 switch语句示例运行结果
从示例代码中不难看出,这种多路选择也可以使用嵌套的if…elseif…else完成。与后者相比,switch看起来逻辑更为清晰,不过其缺点在于:它只能对一个变量进行判断。
3.使用while语句实现循环
【本节示例参考:\\示例代码\\C00\\Example_While】
当程序需要不停执行某种功能,直到达到某种条件才停止,需要采用循环程序结构。例如,当需要输出100次“我不敢了”的时候,就需要用循环结构来实现。while语句可实现程序的循环,它分成二种模式:
(1)while循环,用来在指定的条件内,不断地重覆指定的动作。其语法如下:
1. while (expression) 2. {
3. statement 4. }
(2)do...while循环则先执行一次语句,再判断是否要继续执行,也就是说循环至少执行一次。其语法如下:
1. do 2. {
3. statement 4. }while (expression);
其中的expression为判断的条件,通常都是用逻辑运算符作为判断的条件。而statement为符合条件的执行区段程序,若程序只有一行,可以省略大括号。
下面给出一个实例来说明while循环语句的使用,本例要输出10次“以后不敢了!”的字串,前面并加上数字,表示说了第几次不敢了。
代码0-3 while语句示例:Class1.cs
1. /// 3. ////
4. protected void Button1_Click(object sender, EventArgs e) 5. {{
6. //使用while,循环输出10次“我不敢了!” 7. int i = 0; 8. while (i < 10) 9. {
10. LabelResult.Text += \"我不敢了!\" + \"
\"; 11. i++; 12. } 13. }
while语句示例运行结果如图0.13所示。
图0.13 while语句示例运行结果
4.使用for语句实现循环
【本节示例参考:\\示例代码\\C00\\Example_For】
for语句同样是用来实现循环结构,同while功能类似,其语法为:
1. for (expression1; expression2; expression3) 2. {
3. statement 4. }
expression1:条件的初始值;
expression2:判断的条件,通常用逻辑运算符作为判断的条件;
expression3:执行statement后要执行的语句,用来改变条件,供下次的循环判断,
如累加等。
statement:符合条件时的执行语句,若程序只有一行,可以省略大括号。 下例是用for循环写的“以后不敢了”的例子,可以和while循环进行一下比较。
代码0-4 for语句示例:Class1.cs
1. /// 3. ///
4. protected void Button1_Click(object sender, EventArgs e)
5. {
6. //使用for循环输出10次“我不敢了!”
7. for (int i = 0; i < 10;i++ ) 8. { 9. LabelResult.Text + \"我不敢了!\" + \"
\"; 10. 11. }
}
=
for语句示例运行结果同while示例相同。这里可以很明显的看到for和while循环的区
==
别。在实际应用上,若循环有初始值,且都要累加(或递减),则使用for循环比用while
=
循环要好。 =
5.使用break/continue控制循环
在循环中如果突然想结束循环时,需要使用跳转语句break或continue语句。
Break语句不仅可以用在switch中,也可以用在循环语句中,用于中断循环,从循环中跳出。而continue语句的作用则在于,可以提前结束一次循环过程中执行的循环体,直接进入下一次循环。二者的使用可参考下面示例代码。
代码0-5 break & continue语句示例:Class1.cs
1. /// 2. /// 使用break & continue 3. ///
4. protected void Button1_Click(object sender, EventArgs e) 5. {
=
6. //使用break & continue
7. int i0;
8. for(i0;i<100;i++) 9. { 10. if(i5) continue; 11. if(i>8) break; 12. LabelResult.Text +\"我不敢了!\" + \"
\"; 13. 14. }
}
上面的代码在第10行使用continue直接跳到第6次循环,而当循环到i>8时,则跳出循环,不再执行。调用这个方法的执行结果输出:01234678。
0.4 编码规范
在编写程序时,好的编码规范非常重要,一方面可以便于后期的程序维护和管理,另一方面,具有良好规范的编码可以大大降低开发时程序员犯错误的机会。
0.4.1 好的编码结构
对比下面两段代码,它们的功能相同,都定义了一个矩形类,并包含求面积的方法:
= 代码段A:
=
代码0-6 结构良好的矩形类实现
1. public class Rectangle
2. { 3. public double dblWidth; 4. public double dblHeitht; 5.
6. public Rectangle(double _dblWidth,double _dblHeight) 7. { 8. this.dblWidth=_dblWidth; 9. this.dblHeitht=_dblHeight; 10. } 11. 12. public double GetArea() 13. { 14. return this.dblHeitht*this.dblWidth; 15. } 16. }
代码段B:
代码0-7 结构混乱的矩形类实现
1. public class Rectangle{ 2. public double dblWidth; 3. public double dblHeitht;
4. public Rectangle(double _dblWidth,double _dblHeight){ 5. this.dblWidth_dblWidth; 6. this.dblHeitht_dblHeight; 7. }
8. public double GetArea(){ 9. return this.dblHeitht*this.dblWidth; 10. } 11. }
相信在不作任何解释的情况下,读者还是能够看明白代码A的内容,因为它缩进结构良好,体现了清晰的逻辑结构。而代码B呢?恐怕就困难多了。
可以看出,良好的代码层次结构以及清晰的代码逻辑结构,可以大大提高代码的质量,一方面可以降低程序员出错的可能性,另一方面,在代码出现错误的时候也很容易寻找。
0.4.2 好的注释风格
==
注释可以大大提高代码的可阅读性,另外在编写程序时,还可以帮助程序员具有更清晰的思路。同样,比较0.4.1中的代码段A与下面的代码段: 代码段C
代码0-8 具有良好注释的矩形类实现
1. /// 2. /// 接口:形状 3. ///
4. public interface IShape 5. {
6. ///
16. public class Rectangle: IShape 17. { 18. public double dblWidth; 19. public double dblHeitht; 20. 21. 22. 23. 24. 25.
/// ///
/// 宽 /// 高
//宽 //高
26. public Rectangle(double _dblWidth,double _dblHeight) 27. { 28. this.dblWidth_dblWidth; 29. this.dblHeitht_dblHeight; 30. } 31.
32. /// ///
38. return this.dblHeitht*this.dblWidth; 39. } 40. }
很明显,有了注释之后,完全没有必要对这段代码进行解释了,读者一定能够看懂。另外,VS.NET提供了良好的自动注释功能,在方法或者类前面用“///”添加注释时,会自动生成大量的注释格式,只需要在相应的位置添入注释项即可。
在此推荐尽量使用“///”对类或方法进行注释,这样做还有另外一个好处,当引用这个类或者方法时,VS.NET会自动提示注释的内容。图0.14是在引用Rectangle类的构造函数时的情况。
图0.14 根据方法注释给出提示
这样,在调用方法时便可以更加方便。
0.4.3 好的命名规范
在C#编码中,常常使用到的命名规范有: Pascal大小写规范:所有单词第一个字母大写,其他字母小写。 Camel大小写形式:除了第一个单词,所有单词第一个字母大写,其他字母小写。
在C#中,推荐的命名规范如下:
(1)类名使用Pascal大小写形式,如:
1. public class HelloWorld 2. {
3. … 4. }
(2)方法使用Pascal大小写形式,如
1. public class HelloWorld 2. { 3. void SayHello(string name) 4. { 5. … 6. } 7. }
(3)变量和方法参数使用Camel大小写形式,如:
1. public class HelloWorld 2. { 3. int totalCount = 0; 4. void SayHello(string name) 5. { 6. string fullMessage = \"Hello \" + name;
7. … 8. } 9. }
也可以加前缀以表示变量的类型,但实际上C#并不推荐这种方式。
0.4.4 避免文件过大
在开发中,应尽量避免使用大文件。如果一个文件里的代码超过300~400行,就可以考虑将代码分开到不同的类中。另外,也要尽量避免写太长的方法,一个较理想的方法代码在1~25行之间,方法名应尽量体现其功能。比较下面两段代码: 一个好的类,功能独立的方法尽量分开:
代码0-9 方法功能独立的矩形类实现
1. /// 矩形类
2. public class Rectangle: IShape
3. { 4. public double dblWidth; 5. public double dblHeitht; 6.
7. /// 求矩形面积
8. public double GetArea() 9. { 10. return this.dblHeitht*this.dblWidth; 11. } 12.
13. /// 求周长 14. public double GetRoundLength() 15. { 16. return this.dblHeith+this.dblWidth; 17. } 18. }
//宽 //高
不好的类:
代码0-10 方法功能混乱的矩形类实现
1. /// 矩形类
2. public class Rectangle: IShape 3. { 4. public double dblWidth; 5. public double dblHeitht; 6.
7. /// 求矩形面积和周长 8.
public double GetData (ref double _dblArea, ref double _dblRoundLengh)
//宽
//高
9. { 10. _dblArea this.dblHeitht*this.dblWidth; 11. _ dblRoundLengh = this.dblHeitht+this.dblWidth; 12. } 13. }
第二段代码把多个功能融和在一个方法里,一方面逻辑比较混乱,另外也容易使方法变得非常大,不易管理。
=
因篇幅问题不能全部显示,请点此查看更多更全内容