C#初学者指南(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-13 23:32:25

点击下载

作者:[加拿大]Jayden Ky 著

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

C#初学者指南

C#初学者指南试读:

前言

欢迎阅读本书。

C#(读作“c sharp”)是一种易学的、成熟的编程语言。同时,它也是.NET Framework 的一部分。.NET Framework是很大的一个技术集合,它包罗万象,以至于初学者往往不知从何入手。如果你也是一名初学者,那么本书非常适合你,因为本书就是专门为.NET初学者所编写的教程。

作为初学者的教程,本书并不会介绍.NET Framework中的每一种技术。相反,本书涵盖C#和.NET Framework 语言中最重要的主题,掌握了这些内容,你才能够自学其他的技术。但是本书的内容很全面,在完全理解各章的内容后,你就能很好地完成中级C#程序员的日常任务。

本书介绍了以下三个主题,它们是专业的C#程序员必须要掌握的。● C#程序语言● C#的面向对象编程(Object-Oriented Programming,OOP)● .NET Framework类库

设计一门高效的C#课程,其困难之处就在于,这三个主题实际上是彼此相关的。一方面,C#就是OOP语言,所以如果你已经了解OOP,那么学习C#的语法就较容易。另一方面,诸如继承、多态、数据封装等OOP的特性,我们最好是用真实案例来讲解。可是,理解真正的C#程序,却需要我们具有.NET Framework类库的知识。

因为这三个主题相互依赖,所以我们不能把它们划分为三个独立的部分。相反,讨论一个主题的章节会和讨论另一个主题的章节交织在一起。例如,在介绍多态之前,本书要确保我们已经熟悉某些.NET Framework的类,以便能给出真实的案例。另外,如果不能很好地理解一组特定的类,我们就很难理解泛型这样的语言特性,而这组特定的类又是在讨论完支持类后才介绍的。

本书中也会有一个主题在两三个地方重复出现的情况。例如,for和while循环语句是一个基本的语言特性,应该在前边的章节中介绍它。用foreach循环遍历一个数组或集合,却只能在介绍过数组和集合类型后再讲解。因此,循环语句首先会出现在第3章,然后在第5章介绍数组和第13章介绍集合时,会再次出现。

本前言接下来的内容会给出.NET Framework的高级概述、OOP的介绍、每章的简单介绍以及.NET Framework的安装指南。.NET Framework概述

.NET Framework是一种编程环境的常用名称,其规范的叫法为通用语言基础架构(Common Language Infrastructure,CLI)。CLI是微软开发的并且通过了ISO和ECMA的认证标准。ISO和ECMA都是国际标准化机构。

.NET Framework引人注目的地方之一,就是支持多种编程语言。实际上,最新的统计结果表明,有超过30种语言可以使用.NET Framework,包括Visual Basic、C#和C++。这就意味着,如果习惯于使用Visual Basic,可以继续用这种语言编程。如果你是一名C++程序员,也不必为了充分利用.NET Framework所提供的优势而去学习一种新的语言。

但是,多语言支持并不是.NET Framework的唯一特性。它还提供了一整套技术,使软件开发更迅速且应用程序更加健壮和安全。多年来,.NET Framework成为首选的技术,因为它具有以下优点。● 跨语言集成● 易用性● 平台独立性● 一个可以加速应用程序开发的庞大的类库● 安全性● 可扩展性● 广泛的行业支持

.NET Framework不像传统的编程环境。在传统的编程中,源代码要编译成可执行代码。这个可执行代码对于目标平台来说是本地的,因为它只能在原计划运行的平台上运行。换句话说,在Windows上编写和编译的代码,只能在Windows上运行;在Linux上编写的代码,只能在Linux上运行,依次类推,如图I-1所示。图I-1 传统的编程范式

相反,.NET Framework程序则编译成通用中间语言(Common Intermediate Language,CIL,读作“sil”或“kil”)代码。如果你熟悉Java,CIL代码相当于Java的字节码。CIL代码此前叫作微软中间语言(Microsoft Intermediate Language)或MSIL代码,只能运行在公共语言运行时(Common Language Runtime,CLR)上。CLR是解释CIL代码的一个本地应用程序。因为CLR可用于多个平台,同样的CIL代码也变成了跨平台的代码。如图I-2所示,我们可以用支持的任何语言编写一个.NET程序并且把它编译成CIL代码。同样CIL代码可以运行在任意已经开发了CLR的操作系统上。除了CIL代码以外,.NET编译器还生成了元数据以描述CIL代码中的类型。这个元数据在术语上叫作清单(manifest)。把CIL代码和相应的清单一起打包成一个.dll或.exe文件,叫作程序集。图I-2 .NET编程模型

目前,微软提供了CLR针对Windows的实现,但是随着来自Project Mono(http://www.mono-project.com )和DotGNU Portable.NET(http://dotgnu.org/pnet.html)的其他实现,CIL代码已经能够在Linux、Mac OS X、BSD、Sony PlayStation 3和Apple iPhone上运行了。

.NET术语中把只能在CLR之上运行的代码称为托管代码(Managed code)。另一方面,一些.NET语言,诸如C#和C++,既可以生成托管代码又可以生成非托管代码。非托管代码运行在运行时之外。本书只介绍托管代码。

当用C#或其他.NET语言编程时,我们总是使用通用类型系统(Common Type System,CTS)来工作。在解释CTS前,我们要确定你已经了解了什么是类型。那么,什么是类型呢?在计算机编程中,类型决定了值的种类,例如一个数字或一段文本。对于编译器来说,类型信息特别有用。例如,它使得的3*2这个乘法运算有意义,因为3和2都是数字。但是,我们如果在C#代码中写下VB *C#,编译器将认为它无效,因为不能把两段文本相乘,至少,在C#中不允许这样做。

CTS中有5种类型。● 类● 结构● 枚举● 接口● 委托

在本书中,我们会逐一介绍这些类型。面向对象编程的概述

OOP通过对真实世界中的对象建模应用来工作。OOP有三种主要特性:封装、继承和多态。

OOP的好处是很实际的。这也是为什么包括C#在内的大部分现代编程语言都是OO的。我们甚至可以引用为了支持OOP而进行语言转换的两个著名的例子:C语言演变成了C++,而Visual Basic则升级为Visual Basic.NET。

本节介绍OOP的好处并且对学习OOP的难易程度给出一个评估。OOP的优点

OOP的优点包括代码易维护、代码可复用和可扩展性。下面,我们对这些优点作更详尽的介绍。

1.易维护

当前的应用软件往往非常大。很久以前,一个“大”系统包含几千行代码。而现在,甚至100万行代码都不算是大系统。当系统变得更大的时候,就开始产生一些问题。C++之父Bjarne Stroustrup曾经说过类似于下面的话。小程序可以随便写,即使不是很容易,但最终你还是能让它工作。但是,大程序却截然不同。如果你没有使用“好的编程”技术,新的错误会随着你修正老错误的步伐而不断地产生。

原因就在于,一个大程序的不同部分会相互影响。当我们修改程序的某一部分内容时,可能不会意识到这种变化可能会影响到其他部分。OOP使应用程序更容易模块化,而且模块化使得维护不再头疼。模块化在OOP中是内在的,因为类(它是对象的模板)本身就是一个模块。好的设计应该允许一个类包含相似的功能和相关的数据。在OOP中,一个经常用到的重要的相关术语是耦合,它表示两个模块之间有一定程度的交互。各部分之间的松耦合使得代码更容易实现复用,而复用是OOP的另一个优点。

2.可复用性

可复用性意味着,如果对于最初编写的代码有相同的功能需求,那么代码的编写者或其他人可以复用它们。一种OOP语言通常带有一套现成的库,这并不奇怪。以C#为例,这门语言是.NET Framework的一部分,它提供了一套详细设计并经过测试的类库。编写和发布自己的库也很容易。编程平台中对可复用性的支持是非常吸引人的,因为它会缩短开发时间。

类的可复用性的最大挑战之一就是为类库创建好的文档。程序员如何才能快速地找到提供了他(或她)想要的功能的那个类?找到这样一个类会比从头编写一个新的类更快吗?好在,.NET Framework类库有大量的文档。

可复用性不仅适用于编码阶段类或其他类型的复用,当我们在OO系统中设计一个应用时,OO设计问题的解决方案也可以复用。这些解决方案叫作设计模式。为了更容易地指明每一种解决方案,人们给每种模式都起了一个名称。在经典的设计模式图书《Design Patterns:Elements of Reusable Object-Oriented Software》中,我们可以找到可复用的设计模式的最早的名录,该书作者是Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides。

3.可扩展性

每个应用都是独一无二的,都有自己的需求和规格。说到可复用性,有时我们无法找到一个已有的类能够提供应用程序所需的确切功能。但是,我们可能会找到一个或两个类,它们提供了这些功能的一部分。可扩展性意味着,我们仍然可以使用这些类,通过扩展它们来满足我们的需求。我们还节省了时间,因为不需要从头编写代码。

在OOP中,可扩展性通过继承来实现。我们可以扩展一个已有的类,为它添加一些方法或数据,或者修改不喜欢的方法行为。如果知道该基本功能会在许多示例中使用,但是又不希望类提供非常具体的功能,那么我们可以提供一个通用的类,以后可以扩展它来为应用程序提供具体的功能。OOP很难吗

C#程序员需要熟练掌握OOP。如果你曾经使用过过程式语言,诸如C或Pascal,你会发现有很大的不同。鉴于此,这既是好消息又是坏消息。

我们先说坏消息。

研究人员一直针对在学校教授OOP的最好的方式而争论不休。有些人认为,最好的方法是在介绍OOP前先教授过程式语言。我们发现,在许多学校,OOP课程往往安排在接近大学最后1年。

但是,最新的研究表明,拥有过程式编程技能的人和OO程序员的视角以及解决问题的模式差异迥然。当熟悉过程式编程的人需要学习OOP时,他所面临的最大障碍就是模式的转变。据说,从过程式转变到面向对象模式,这种观念的转变需要6~18个月的时间。其他的研究也表明,没有学习过过程式编程的学生,不会觉得OOP很难。

我们再来说好消息。

C #是学习OOP的最简单的语言之一。例如,我们不需要担心指针,也不需要花费宝贵的时间去解决由于没有释放不用的对象而引起的内存泄漏的问题。最重要的是,.NET Framework有一个非常广泛的类库,在其早期的版本中,bug相对来说很少。一旦我们掌握了OOP的基本要点,用C#编程是很容易的。关于本书

本书每一章的内容可以概述如下。

第1章,“初识C#”。本章编写了一个简单的C#程序,然后用csc工具编译并运行它。另外,本章还给出关于编码惯例和集成开发环境的一些建议。

第2章,“语言基础”介绍了C#语言的语法,还介绍了字符集、基本类型、变量和运算符等。

第3章,“语句”,介绍了C#中的for、while、do-while、if、if-else、switch、break和continue等语句。

第4章,“对象与类”,是本书中的第一节OOP课程。本章通过解释什么是C#对象以及如何在内存中存储它开始了对OOP的学习,然后继续介绍了类、类成员以及两个OOP的概念(抽象和封装)。

第5章,“核心类”介绍了.NET Framework类库中重要的类:System.Object、System.String、System.Text.StringBuilder和System.Console,还介绍了数组。本章非常重要,因为本章所介绍的类是.NET Framework中最常用到的一些类。

第6章,“继承”,介绍了OOP的特性之一——继承,它使得代码可以扩展。本章介绍了如何扩展一个类、影响子类的可访问性以及覆盖方法等内容。

第7章,“结构”,介绍了CTS的第二种类型——结构。本章强调了引用类型和值类型之间的不同,介绍了.NET Framework类库中经常用到的一些结构。本章还介绍了如何编写自己的结构。

毋庸置疑,错误处理在任何编程语言中都是一项重要特性。作为一门成熟的语言,C#有非常健壮的错误处理机制,它能防止bug四处蔓延。第8章“错误处理”详细介绍了这种机制。

第9章,“数字和日期”,介绍了在使用数字和日期时所要处理的三个问题:解析、格式化和操作。本章还介绍了可以帮助我们完成这些任务的.NET类型。

第10章,“接口和抽象类”,解释了接口远不只是没有实现的类那么简单。接口定义了服务提供者和客户之间的一个契约。本章还介绍了如何使用接口和抽象类。

第11章,“枚举”,介绍了如何使用关键字enum来声明一个枚举类型。本章还描述了如何在C#程序中使用枚举。

第12章,“泛型”,介绍了泛型。

第13章,“集合”,介绍了如何使用System.Collections.Generic命名空间的成员来组织对象和操作它们。

第14章,“输入和输出”,介绍了流的概念,而且介绍了如何使用流来执行输入和输出的操作。

你会发现第15章“WPF”的内容很有趣,因为我们将学习编写有漂亮用户界面和易用控件的桌面应用程序。

多态是OOP的主要支柱之一。当一个对象的类型在编译时不为人知的时候,多态是非常有用的。第16章“多态”介绍了这种特性并且提供了有用的示例。

访问数据库并且操作数据,这是商业应用程序中最重要的一项任务。目前有许多种不同的数据库服务器,访问不同的数据库需要不同的技能。在第17章“ADO.NET”中,我们介绍如何访问数据库以及操作数据库中的相关数据。

附录A,“Visual Studio Express 2012 for Windows Desktop”,介绍了一款免费的集成开发环境(Integrated Development Environment,IDE),它能帮助我们更有效地编写代码。Visual Studio Express 2012 for Windows Desktop运行在Windows 7和Windows 8上,如果你使用这类操作系统,应该考虑使用它。如果你使用更早版本的Windows,那么可以选择Visual C# 2010 Express作为IDE,我们会在附录B“Visual C# 2010 Express”中介绍它。

最后,附录C介绍了如何安装SQL Server 2012 Express这款免费的软件并创建了一个数据库。下载和安装.NET Framework

在开始编译和运行C#程序前,我们需要下载和安装.NET Framework软件。

默认情况下,在.NET Framework出现后发布的Windows操作系统会包含某个版本的.NET Framework软件。Windows 7附带的是.NET Framework 3.5。因此,如果你需要版本4或4.5,那就需要单独安装它。如果你计划使用Visual Studio,那么你很幸运,因为它已经包含了某个版本的.NET Framework,不需要再单独安装。否则,你可以通过以下链接下载4.5版本。http://msdn.microsoft.com/en-us/library/5a4x27ek.aspx

要在命令行进行编译,我们需要把包含csc.exe文件(C#编译器)的路径添加到PATH环境变量中。这个路径是C:\Windows\Microsoft.NET\Framework\v4.x.y,其中x和y是版本号。x和y的实际值要根据所安装的版本来决定。例如,作者计算机上的版本是4.0.30319。

如果你使用的是64位的计算机,那么路径可能如下所示:C:\Windows\Microsoft.NET\ Framework64\v4.x.y。

要给PATH变量添加一个路径,我们首先需要用鼠标右键点击桌面上的“My Computer”图标,选择“Properties”菜单项。其次在弹出的对话框中,点击位于“Advanced”标签页或“Advanced system settings”标签页上的“Environment Variables”按钮。最后在弹出的对话框中,把上述路径添加到System变量列表框中当前的Path变量的末尾。请注意,每条路径之间必须要用分号隔开。选择一个IDE

IDE是每一位程序员都要使用的工具。大多数现代IDE通过帮助程序员更早地找到bug、debug并跟踪程序,从而显著地提高生产效率。

就.NET Framework开发而言,它有很多IDE可用,但是Microsoft Visual Studio显然是赢家。好在,精简版的Visual Studio,Visual Studio Express 2012 for Windows Desktop(针对Windows 7和Windows8 用户)和Visual C# 2010 Express(针对较早的Windows版本)是免费的。如果你还没有IDE,那么应该现在就去下载并安装它。在第一次使用后,你还需要注册软件,以便继续使用它。

注册是免费的。下载程序示例

本书的程序示例以及每章中问题的答案可以从以下网址下载。http://books.brainysoftware.com/download/csharp.zip

首先将这个zip文件解压缩到一个工作路径中。现在可以开启你的C#编程之旅了。第1章初识C#

开发一款C#程序,包括编写代码、把它编译成通用中间语言(Common Intermediate Language ,CIL)编码以及运行CIL编码。作为一名C#程序员,你会不断地重复这个过程,而熟悉和习惯这个过程也是至关重要的。因此,本章的主要目标是,帮助你体验在Visual Studio Express 2012 for Windows Desktop 或Visual C# 2010 Express这两种免费的微软IDE中使用C#来进行软件开发的过程。

编写的代码不仅能工作,而且要易读和可维护,这一点是很重要的。本章将介绍C#编码惯例。

本章及以后章节的示例代码都假设用Visual Studio Express 2012 for Windows Desktop或Visual C# 2010 Express 开发。1.1 第一个C#程序

本节重点介绍C#开发的步骤:编写程序、把它编译成CIL编码并且运行CIL编码。这里你将会用到Visual Studio Express 2012 for Windows Desktop 或Visual C# 2010 Express,可以通过微软的官方网站免费下载它们。如果你还没有安装IDE,请先安装IDE。Visual Studio Express 2012 for Windows Desktop适合运行在Windows 7和Windows 8上,如果你使用这类操作系统,应该考虑使用它;否则,请下载和安装Visual C# 2010 Express,可以参见附录A或附录B。1.1.1 启动IDE

启动 IDE。打开程序后,你会看到如图1-1或1-2所示的界面。如果软件无法打开,那是因为还没有注册,你应该马上去注册。注册是免费的,而且很简单,更多信息请参见附录A和附录B。图1-1 Visual Studio Express 2012的启动界面图1-2 Visual C# 2010 Express已准备就绪

两个IDE窗口看上去不同,但是都提供了类似的功能。因此下文中我们只介绍在Visual C# 2010 Express的截屏图。

点击“New Project”图标创建新的项目,然后选择“Console Application”,如图1-3所示。图1-3 创建一个新的项目

接受ConsoleApplication1作为解决方案和项目名称,然后点击“OK”按钮,你就会看到所创建的项目和解决方案,如图1-4所示。更棒的是,Visual C# 2010 Express还创建了一个附带一些样板代码的程序文件,如图1-3所示。注意,项目就是一个便于管理应用的容器。它包含C#源代码文件、图片和视频文件等其他的资源文件以及描述应用的记录文档。当创建一个项目时,Visual C# 2010 Express还创建一个解决方案。解决方案是另一种容器,它可以包含一个或多个项目。图1-4 创建的解决方案和项目

现在,你可以开始编写代码了。1.1.2 编写C#程序

在static void Main(string[] args)后边的大括号中插入如下两行语句。Console.WriteLine("Hello World!");Console.ReadLine();

程序清单1.1展现了完整的程序代码,新插入的语句用加粗字体表示。程序清单1.1 一个简单的C#程序using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{  class Program  {    static void Main(string[] args)    {      Console.WriteLine("Hello World!");      Console.ReadLine();    }  }}

另外,你可以双击本书附带的zip文件中的.sln文件查看,zip文件可以从本书站点下载。1.1.3 编译和运行C#程序

用Visual C# 2010 Express开发真的非常简单。要编译代码,直接按下“F5”键或者点击工具栏上的Start 按钮即可。Start按钮是绿色的,如图1-5所示。图1-5 Start按钮

如果程序编译成功,Visual C# 2010 Express将会运行这个程序。你可以在控制台看到文本“Hello World!”,如图1-6所示。图1-6 运行这个程序

恭喜,你已经成功编写了第一个C#程序。在欣赏完第一个程序后,你可以按下“Enter”键来关闭控制台。本章唯一的目的就是让你熟悉编写和编译的过程,我们就不再试图去解释程序是如何工作的了。1.2 C# 编码惯例

编写能够正确运行的C#程序很重要。但是,代码的易读性和易维护性也是至关重要的。可以说,一款软件80%的生命周期是用在维护上。程序员的流动率是很高的,因此其他人来维护你编写的代码的可能性也是很大的。任何接手你所编写的代码的人,都会因为你编写的源代码干净并且易读而心存感激。

使用一致的编码惯例是使你的代码更易阅读的一种方法(其他方法还包括正确的代码组织和充分的注释)。编码惯例包括文件名、文件组织、缩进、注释、声明、语句、空白以及命名惯例。微软发布了一个文档,描述了微软员工需要遵守的标准。该文档的链接如下。http://msdn.microsoft.com/en-us/library/ff926074.aspx

本书的示例程序都会遵循该文档所建议的惯例。我们也希望你能在编程生涯的第一天就养成习惯,遵守这些惯例,以便在今后能自然而然地编写出干净的代码。1.3 小结

本章用Visual Studio Express 2012 for Windows Desktop或Visual C# 2010 Express帮助你编写了第一个C#程序。你已经成功地编写、编译和运行了你的程序。第2章语言基础

C#是一种面向对象编程(Object-Oriented Programming,OOP)的语言,因此对于OOP的理解是至关重要的。本书会在第4章开始介绍OOP。但在了解更多OOP的特性和技术前,我们先要学习以下内容,即本章所介绍的基本的编程概念,包括如下主题。● 编码集:C#支持Unicode字符编码集,程序元素名称不仅局限于

ASCII(American Standard Code for Information Interchange,美

国信息交换标准代码)字符。几乎可以使用目前所有的人类语言

来编写文本。● 内建类型:在.NET类库中,这些类型中的每一种都有一个缩写

名称或别名,例如,int就是System.Int32 结构的缩写名称。● 变量:变量就是能够改变其内容的占位符。变量的类型有很多种。● 常量:值不能改变的占位符。● 直接量:直接量是C#编译器所能够理解的数据值的表示。● 类型转换:将一种数据类型转换为另一种类型。● 操作符:操作符是所要执行的某种操作的表示。

注意Java和C++是在C#之前两种常用的编程语言,如果你

曾用它们编写过程序,那么在学习C#时会觉得很容易上

手,因为C#语法与Java和C++很相似。但是,C#的发明者

增加了一些Java和C++中所没有的特性,也删掉了一些Java

和C++中已有的特性。2.1 ASCII和Unicode

传统上,在讲英语的国家计算机只使用ASCII字符集来表示字母和数字字符。ASCII码中每个字符用7位表示,该字符集中一共有128个字符,包括了小写和大写的拉丁字母、数字和标点符号。

ASCII字符集后来又扩展并增加了128个字符,包括像德语字符ä、ö、ü和英国货币符号£。这个字符集叫做扩展ASCII,每个字符用8位来表示。

ASCII和扩展ASCII仅仅是众多可用字符集中的两种。另一种常用的字符集是ISO(国际标准组织)制定的ISO-8859-1标准,也叫做Latin-1。在ISO-8859-1中,每种字符同样是用8位表示。这个字符集包括许多西欧国家语言书写所用到的所有字符,例如德语、丹麦语、荷兰语、法语、意大利语、西班牙语、葡萄牙语,当然也包括英语。每字符8位的字符集很方便,因为一个字节正好是8位。因此,存储和传送8位字符集编写的文本是最高效的。

然而,不是每种语言都使用拉丁字母。中文、韩语和泰语就是使用不同字符集的语言。例如,在中文中,每个字符表示一个汉字,而不是一个字母。有成千上万这样的字符,8位无法表示字符集中所有的字符。日语也使用自己的不同的字符集。总而言之,针对世界上所有的语言,会有成百上千的字符集。这样就会很混乱,因为在一个字符集中表示一个特定字符的代码,在另一个字符集中会表示一个完全不同的字符。

Unicode是由一个叫做Unicode Consortium(www.unicode.org)的非营利组织开发的字符集。它试图把世界上所有语言的所有字符放到一个字符集中。在Unicode中,唯一的一个数字精确地表示一个字符。Unicode用于.NET Framework、Java、XML、ECMAScript和LDAP等语言中,当前的版本是Unicode 6。它也被诸多业内领导者所采用,诸如IBM、Microsoft、Oracle、Google、HP、Apple等。

最初,每个Unicode字符用16位表示,能够表示超过65000个字符。65000个字符足以对世界上主要语言的大部分字符进行编码。然而,Unicode Consortium计划要对超过一百万个字符进行编码。要满足这么大的数量,你就需要比16位更大的存储空间来表示每个字符。事实上,我们认为32位系统可以非常方便地存储Unicode字符。

现在,我们已经发现了一个问题。当Unicode为所有语言中所有用到的字符提供足够的空间,存储和传送Unicode文本就不会像存储和传送ASCII或Latin-1字符那样高效。在互联网世界,这是一个大问题。想象一下传送4倍于ASCII文本数据的数据是什么样子?

好在字符编码可以使Unicode文本的存储和传送更高效。我们可以把字符编码理解成数据压缩。现在,有很多种字符编码可用,Unicode Consortium支持其中的3种。● UTF-8:这对于HTML以及将Unicode字符转换为可变长度的字节

编码的协议很常见。UTF-8的优势在于,它与人们所熟知的

ASCII字符集一致,拥有和ASCII相同的字节值,并且有许多现成

软件可以把Unicode字符转换成UFT-8。大多数浏览器都支持

UTF-8字符编码。● UTF-16:在这个字符编码中,所有常用的字符都存放在一个独

立的16位的编码单元中,其他不常用的字符可以通过成对的16

位编码单元来访问。.NET Framework使用这种字符编码。● UTF-32:这种字符编码为每个字符使用32位。显然,这不是

Internet应用的选择。至少,目前不是。

ASCII字符在软件编程中仍然扮演着主要的角色。C#对大部分输入的元素使用ASCII码,除了注释、标识符以及字符和字符串内容以外。对于后者,C#支持Unicode字符。也就是说,你可以使用英语之外的其他语言写注释、标识符和字符串。例如,如果你是住在北京说中文的人,你可以用中文字符作为变量名称。下面这句C#代码声明一个名为password的标识符,它由ASCII字符组成。string password = "secret";

与之相对,如下的标识符用简体中文字符表示。string 密码 = "secret";2.2 内建类型和通用类型系统

C#是一种强类型语言,这意味着每条数据必须有一个类型,对于变量这样的数据占位符也是一样的。C#定义了各种所谓的内建类型。

与此同时,.NET Framework支持多种编程语言,并且用一种语言编写的代码可以与另一种语言编写的代码交互操作。为了促进这种语言的互操作性,.NET Framework设计人员定义了通用类型系统(Common Type System,CTS)。CTS指定了运行时(也就是CLR,公共语言运行时)所支持的所有数据类型。用一种语言编写的程序要被另一种语言编写的程序所调用,这就要求前一个程序只能被转换成CTS兼容的类型。

C#既支持兼容CTS的内建数据类型,也支持不兼容CTS的内建数据类型。但是,转换成不兼容CTS的数据类型的C#代码,可能就无法很好地与其他语言编写的代码交互操作。表2-1列举了C#的内建类型。表2-1 C#内建类型C# 类.NET 类大小 (字节)值/区间型型byteByte10~255charChar2任意Unicode字符boolBoolean1true或falsesbyte*SByte1−128~127shortInt162−32 768~32 767ushort*UInt1620~65 535intInt324−2 147 483 648~2 147 483 647uint*UInt3240~4 294 967 295Singlefloat4−3.402823e38~3.402823e38−1.79769313486232e308~doubleDouble81.79769313486232e308decimDecimal16±1.0 × 10e28 to ±7.9 × 10e28al−9,223,372,036,854,775,808~longInt6449,223,372,036,854,775,807ulong*UInt6440~18446744073709551615 stringString字符序列 objectObject所有其他类型的基类型

星号标出的4个内建类型(sbyte、ushort、uint、ulong)都不兼容CTS,这意味着其他语言使用它们可能会有问题。使用不兼容CTS类型要非常慎重。

初学者经常很难选择数据类型,其实作出选择并不难。第一条规则就是必须要确定该类型是数字或非数字。如果不是数字,你可以选择bool、char或string。bool类型有两种状态,真或假(是或否)。char类型可以包含一个Unicode字符,如“a”、“9”或“&”。Unicode也允许char包含那些在英文字母中不存在的字符,例如日语字符“の”。string是一个字符序列,也是编程中最常用到的数据类型。

例如,要表示某个结果是否使用过,bool是很好的选择。在C#中,你可以写成如下格式。bool used;

但是,如果结果是3种条件之一(新的、用过的、不确定),那么就不能用布尔类型,因为3种状态对于这种数据类型来说太多了。你可以用一个数值类型来替代,如byte。

选择数据类型的第二条规则是使用占空间最小的类型。这条规则尤其适用于数值类型。byte、sbyte和int都能保存整数。但是,如果保存的数字小于10,你可以选用byte或sbyte,因为它们只占用一个字节,而int需要占用4个字节。

另外,如果一个值不能是负数,要选择无符号类型。例如,年龄用byte保存而不用sbyte。byte Age;

在这个例子中,byte就足够了,因为没有人能活到200岁。但是,如果要表示一个国家的人口数量,我们可能就要用int了。稍等,难道int不是一个有符号的数据类型吗?一个国家的人口数量怎么会是负数呢?没错,人口数量不会是负数,最接近的可选类型是unit,但是它不兼容CTS。我们要尽量避免使用任何不兼容CTS的类型,即使用其他数据类型可能会开销更大。如果要选择一个能够包含数字0到4 000 000的数据类型,我们会用long(8个字节宽),而不是用uint(4个字节宽),除非内存确实是个大问题。

byte、short、int和long数据类型只能保存整数,有小数点的数字我们需要用float或double。2.3 变量

变量是数据占位符。C#是强类型语言,因此每个变量必须有一个声明的类型。在C#中,有两种数据类型。● 引用类型:引用类型的变量提供了对对象的引用。● 基本类型:基本类型变量保存了一个基本数据。

除了数据类型之外,C#变量也是一个名称或一个标识符。选择标识符有一些基本规则。(1)标识符是一个长度没有限制的字母和数字组成的序列。标识符必须以字母或下划线开头。(2)标识符不能是C#关键字(如表2-2所示)、bool值或null值。(3)标识符在作用域内必须是唯一的。作用域我们会在第4章中介绍。表2-2 C#关键字abstractdoinprotectedtrueaspublictrydoubleintreadonlyTypeofbaseelseinterfaceenumboolinternalrefuintulongeventreturnbreakisbyteexplicitsbytelockuncheckedcaselongexternsealedunsafenamespacecatchfalseshortushortfinallynewusingcharsizeofcheckedfixednullstackallocvirtualobjectclassfloatstaticvoidoperatorstringconstforvolatileoutstructcontinueforeachwhile gotodecimaloverrideswitch paramsdefaultifthis delegateimplicitprivatethrow

注意关键字加上@前缀,就可以当作标识符使用。

下面是一些合法的标识符。salaryx2_x3@class row_count密码

下面是一些不合法的标识符。2x class c#+variable

2x是不合法的,因为它是以数字开头的。class是一个关键字。c#+variable是不合法的,因为它包含了一个#符号和一个加号。

这里还要注意名称是区分大小写的。x2和X2是两个不同的标识符。

声明一个变量要先给出类型,然后在名称后加上一个分号。下面是变量声明的一些示例。byte x;int rowCount;char c;

上面示例中声明了3个变量。● byte类型的变量x;● int类型的变量rowCount。● char类型的变量c

x、rowCount和c是变量名称或标识符。

我们也可以在一行中声明相同类型的多个变量,变量之间用逗号隔开。例如以下语句。int a, b;

它等同于以下语句。int a; int b;

但是,我们不建议在一行中写多个声明,因为这样会降低易读性。

最后,我们可以在声明变量的同时给它指定一个值。byte x = 12;int rowCount = 1000;char c = 'x';2.4 常量

在C#中,可以在一个变量声明前加上关键字const,使得这个值成为不可改变的。例如,一年中的月份数目是固定不变的,所以你可以写成如下格式。const int NumberOfMonths = 12;

再看一个例子,在一个执行数学运算的类中,你可以声明一个变量pi,它的值等于22/7(一个圆的圆周除以它的直径,在数学中用希腊字母π来表示)。const float pi = (float) 22 / 7;

一旦赋了值,这个值就不能再改变了。如果你试图改变它,将会导致编译错误。

注意,22/7前边的(float)是用来把除后的值转换成float类型。如果不这样做,结果会返回int类型,pi变量的值就是3,而不是3.142857。

还需要注意的是,既然C#使用Unicode字符,如果你不觉得π比pi更难输入的话,那么可以把变量pi直接定义成π。const float π= (float) 22 / 7;2.5 直接量

在程序中,经常需要给变量赋一个值,例如把数字2赋予一个int变量,把字符“c”赋予一个char变量。因此,需要用C#编译器能够理解的格式来写出值的表现形式。值的源代码表示就叫作直接量。有3种类型直接量:基本类型直接量、字符串直接量和null直接量。本章只介绍基本类型的直接量。null直接量会在第4章介绍,字符串直接量会在第5章讲述。

基本类型直接量有4种子类型:整型直接量、浮点型直接量、字符型直接量和布尔型直接量。这些子类型说明分别如下。2.5.1 整型直接量

整型直接量可以写成十进制(有时候也说,以10为基数)、十六进制(以16为基数)和八进制(以8为基数)。例如,一百可以表示成100。下面是十进制的整型直接量。2123456

下面的另一个示例代码把10赋予int类型的变量x。int x = 10;

十六进制整型用前缀0x或0X表示,例如,十六进制数字9E写成0X9E或0x9E 。八进制整型用前缀数字0表示,例如,八进制数字567表示为如下格式。0567

整型直接量用于为byte、short、int和long这些变量类型赋值,要注意的是,所赋的值不能超过变量的容量。例如,byte类型数字最大就是255。下面的代码会导致编译错误,因为500对于byte来说太大了。byte b = 500;

注意,long直接量可以加上后缀L。long productId = 9876543210L;2.5.2 浮点型直接量10

像0.4、1.23、0.5e这样的数字都是浮点数。浮点数包含以下部分。● 整数部分● 小数点● 小数部分● 可选的指数

以1.23为例,这个浮点数的整数部分是1,小数部分是23,没有10可选的指数部分。0.5e的整数部分是0,小数部分是5,10是指数。

.NET Framework中有两种类型的浮点数:float和double。在float和double中,作为零的整数部分是可选的。换句话讲,也就是0.5可以写成.5。指数部分可以用e或E表示。

要表示float变量,你可以使用如下的格式之一。Digits . [Digits] [ExponentPart] f_或_F . Digits [ExponentPart] f_或_F Digits ExponentPart f_或_F Digits [ExponentPart] f_或_F

请注意,括号中的部分是可选的。

F或f表示浮点数直接量是float类型,如果没有这一部分的话,会导致浮点数直接量成为double类型。要更明确表示double直接量,也可以加上后缀D或d。

要表示double类型的直接量,你可以使用如下的格式之一。Digits . [Digits] [ExponentPart] [d_或_D]. Digits [ExponentPart] [d_或_D]Digits ExponentPart [d_或_D]Digits [ExponentPart] [d_或_D]

在float和double中,ExponentPart的定义如下所示。ExponentIndicator SignedInteger

ExponentIndicator是e或E。SignedInteger是Signopt Digits。

Sign是+或−,加号是可选的。

float直接量的示例如下所示。2e1f8.f.5f0f3.14f9.0001e+12f

double直接量的示例如下。2e18..50.0D3.149e-9d7e123D2.5.3 布尔型直接量

bool类型有两个值,用直接量表示就是true和false。例如,下面的代码声明一个bool变量includeSign并给它赋值为true。boolean includeSign = true;2.5.4 字符型直接量

字符型直接量是用单引号括起来的Unicode字符或转义序列。转义序列就是一个Unicode字符的表现形式,这个Unicode字符无法通过键盘输入,或者它在C#中具有特殊的作用。例如,回车和换行字符用于结束一行,它们没有可见形式。要表示换行字符,你就需要对其转义,也就是写出其字符表现形式。单引号字符也需要转义,因为单引号是用来将字符包围起来的。

如下是字符直接量的示例。'a''z''A''Z''0''ü''%''我'

如下是作为转义序列的字符直接量。'\b'  退格键字符'\t'  tab键字符'\\'  反斜线'\''  单引号'\"'  双引号'\n'  换行 '\r'  回车

另外,C#允许转义一个Unicode字符,以便你用ASCII字符序列来表示一个Unicode字符。例如,字符 ⊙的Unicode编码是2299,你可以用下面的字符直接量来表示这个字符。'⊙'

然而,如果你不能通过键盘来生成那个字符,可以用下面的方式转义它。'\u2299'2.6 基本类型转换

在处理不同数据类型时,我们经常需要执行转换。例如,将一个变量的值赋予另一个变量就涉及转换。如果变量都是相同类型,赋值总是会成功。从一种类型转换成相同类型叫做恒等转换。例如,下列操作能够确保成功。int a = 90;int b = a;

但是,不同类型的转换就不能确保成功,甚至不可能。这里还有两种其他基本类型的转换,宽化转换和窄化转换。2.6.1 宽化转换

宽化基本类型转换是指,从一种类型到另一种类型转换时,后者的大小和前者一样大甚至更大,例如从int(32位)到long(64位)。宽化转换在下列情况中是允许的。● byte到short、int、long、float或double● short到int、long、float或double● char到int、long、float或double● int到long、float或double● long到float或double● float到double

从一种整数类型到另一种整数类型的宽化转换是不会丢失信息的。同样,从float到double的转换也会保留全部信息。但是,从int或long到float的转换,可能会导致准确度降低。

宽化基本转换隐式地进行,我们不需要在代码中做任何事。例如:int a = 10;long b = a; // 扩大转换2.6.2 窄化转换

窄化转换是从一种类型到另一种更小的类型的转换,例如,从long(64位)到int(32)位。通常,窄化基本类型转换在下列情况下产生。● short到byte或char● char到byte或short● int到byte、short或char● long到byte、short或char● float到byte、short、char、int或long● double到byte、short、char、int、long或float

和宽化基本类型转换不同,窄化基本类型转换必须是显式的,需要在圆括号中指定目标类型。例如,下面是long到int的窄化转换。long a = 10;int b = (int) a; // 窄化转换

代码第2行中的(int)告诉编译器要做一个窄化转换。

如果要转换的值大于目标类型的容量,窄化转换可能会导致信息丢失。上一个示例没有出现信息丢失是因为10对于int来说足够小。但是,下面这个转换例子中会有一些信息丢失,因为9876543210L对于int来说太大了。long a = 9876543210L;int b = (int) a; // b的值现在是1286608618

窄化转换引起信息丢失,会使程序产生缺陷。2.7 运算符

计算机程序就是实现特定功能的操作的集合。运算有很多种,包括加减乘除和位移。在本节中,我们将学习各种C#操作。

一个运算符带上一个、两个或三个操作数来执行操作。操作数是操作的对象,运算符是表示行为的符号。例如,以下为加法操作。x + 4

这个例子中,x和4是操作数,+是运算符。

运算符可能返回结果,也可能不返回结果。

注意任何合法的运算符和操作数的组合叫做表达式。例如,

x + 4就是一个表达式。布尔型表达式的返回结果是true或

false。整型表达式生成一个整数。浮点型表达式的结果是浮

点数。

需要一个操作数的运算符叫做一元运算符。C#中只有少数几个一元运算符。C#中最常见的运算符类型是二元运算符,它需要两个操作数。另外C#中只有一个三元运算符,即 ? : ,它需要3个操作数。表2-3中列出了C#运算符。表2-3 C# 运算符=>=!=&&++−−|+−<<>>>>>/&%^*|=+=−=<<=>>=>>>=/=&=%=*=^=

C#中有6组运算符。● 一元运算符● 算术运算符● 关系和条件运算符● 位移和逻辑运算符● 赋值运算符● 其他运算符

这些运算符我们会在下文中介绍。2.7.1 一元运算符

一元运算符操纵一个操作数。有6个一元运算符,本节都会介绍。

一元运算符 −

一元运算符−,返回结果是对操作数取反。操作数必须是一个数值或一个数值变量。例如,下列代码中,y的值是−4.5。float x = 4.5f;float y = -x;

一元运算符 +

这个运算符返回操作数的值。操作数必须是数值或一个数值基本类型的变量。例如,下面的例子中,y的值是4.5。float x = 4.5f;float y = +x;

这个运算符不太重要,因为没有它也不会有什么不同。

递增运算符 ++

递增运算符对操纵的操作数加1。操作数必须是数值类型的变量。运算符可以在操作数之前或之后。如果运算符在操作数之前,叫作前缀递增运算符;如果在操作数之后,就称为后缀递增运算符。

下例是前缀递增运算符。int x = 4;++x;

在执行++x之后,x的值是5。上面代码和下面代码是一样的。int x = 4;x++;

在执行x++之后,x的值是5。

然而,如果把递增运算符的结果赋值给同一个表达式中的另一个变量,那么前缀运算符和后缀运算符截然不同,参考例子如下。int x = 4;int y = ++x;// y = 5, x = 5

前缀递增运算符在赋值之前应用,x会增加到5,然后把这个值复制给y。

但是,注意一下如下的后缀递增运算符的使用。int x = 4; int y = x++; // y = 4, x = 5

使用后缀递增运算符,操作数(x)在赋值给另一个变量(y)之后,才会增加1。

请注意,递增运算符最常用于int类型。然而,它也能应用于其他数值类型,例如float类型和long类型。

递减运算符−−

递减运算符对操纵的操作数减1。操作数必须是数值类型的变量。与递增运算符一样,它也分为前缀递减运算符和后缀递减运算符。例如,下列代码中x先递减,然后赋值给y。int x = 4;int y = --x; // x = 3; y = 3

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载