第 1 章 c# 入门基础

521
C# 从入门到实践 第1章 C# 入门基础 Microsoft 公司是这样描述 C# 的:“ C# 是从 C 和 C++ 派生 来的一种简单、现代、面向对象和类型安全的编程语 言。 C# (读做 'Csharp' )主要是从 C/C++ 编程语言家 族移植过来的, C 和 C++ 的程序员会马上熟悉它。 C# 试图结合 Visual Basic 的快速开发能力和 C++ 的强大灵 活的能力。”。本章将讲解使用 C# 语言开发的入门知识, 主要介绍以下知识点。 .NET Framewrok ; 搭建 Visual Studio 2008 开发环境; 创建第一个控制台应用程序; 创建第一个 Windows 窗体应用程序。

Upload: baina

Post on 25-Jan-2016

61 views

Category:

Documents


4 download

DESCRIPTION

第 1 章 C# 入门基础. Microsoft 公司是这样描述 C# 的:“ C# 是从 C 和 C++ 派生来的一种简单、现代、面向对象和类型安全的编程语言。 C# (读做 'Csharp' )主要是从 C/C++ 编程语言家族移植过来的, C 和 C++ 的程序员会马上熟悉它。 C# 试图结合 Visual Basic 的快速开发能力和 C++ 的强大灵活的能力。”。本章将讲解使用 C# 语言开发的入门知识,主要介绍以下知识点。 .NET Framewrok ; 搭建 Visual Studio 2008 开发环境; 创建第一个控制台应用程序; - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 1 章   C# 入门基础

C#从入门到实践

第 1 章 C# 入门基础

Microsoft 公司是这样描述 C# 的:“ C# 是从 C和 C++ 派生来的一种简单、现代、面向对象和类型安全的编程语言。 C# (读做 'Csharp' )主要是从 C/C++ 编程语言家族移植过来的, C和 C++ 的程序员会马上熟悉它。 C# 试图结合 Visual Basic 的快速开发能力和 C++ 的强大灵活的能力。”。本章将讲解使用 C# 语言开发的入门知识,主要介绍以下知识点。

.NET Framewrok ; 搭建 Visual Studio 2008 开发环境; 创建第一个控制台应用程序; 创建第一个 Windows 窗体应用程序。

Page 2: 第 1 章   C# 入门基础

C#从入门到实践

1.1 C# 概述

C# 是一种简单的、现代的、面向对象的、类型安全的编程语言。它不但提供了面向对象编程的技术,而且还提供了面向组件编程的支持技术。 Visual C# 2008 提供了许多方便开发的工具,如高级代码编辑器、方便的用户界面设计器、集成调试器等。开发人员使用这些工具,可以更容易在 C# 语言 3.0 版和 .NET Framework 3.5 版的基础上开发应用程序。 (源码网整理: www.codepub.com)

Page 3: 第 1 章   C# 入门基础

C#从入门到实践

1.1.1 C# 语言

C# 是一种 Microsoft 公司设计的、简洁的、类型安全的、面向对象的语言,它松散地基于 C/C++ 语言,并且有很多方面和 Java 语言类似。开发人员可以使用 C# 语言来构建在 .NET Framework 上运行的各种安全、可靠的应用程序。

C# 语法表现力强、简单易学、容易上手。通常地,开发人员通过很短的时间的学习,就能够使用 C# 语言开发高效的程序。 C# 语法提供了许多强大的功能,如可为空置( null )的值类型、枚举、委托、 lambda 表达式、直接内存访问等。 C# 支持泛型类型和方法,进而提供了更为出色的类型安全和性能。特别地, C# 还提供了迭代器、语言集成查询( LINQ )表达式等高级功能,使得开发人员可以在 C# 代码中创建具有查询功能的程序代码。

Page 4: 第 1 章   C# 入门基础

C#从入门到实践

1.1.2 .NET 框架

C# 程序必须在 .NET Framework 上运行。 .NET Framework是Windows 的一个不可或缺的组件,是一个支持构建、部署和运行下一代应用程序和 Web 服务的完整 Windows 组件。 .NET Framework 能够提供效率极高的、基于标准的多语言(如 C#、 VB.NET、 C++、 J# 等)环境,能够将现有的应用程序与下一代应用程序和服务集成,并能迅速部署和操作 Internet 规模的应用程序。 .NET Framework 主要包括两个组件:公共语言运行库( Common Language Runtime ,简称为 CLR )和 .NET Framework 类库( Class Library )。

1 .公共语言运行库2. .NET Framework 类库3 .公共语言运行库、 .NET Framework 类库和应用程序的关系4 .语言互操作性5. C# 应用程序执行流程

Page 5: 第 1 章   C# 入门基础

C#从入门到实践

1.1.3 C# 应用程序

C# 应用程序包括两种应用程序:控制台( Console )应用程序( 1.3 小节创建的应用程序就是一个控制台应用程序)和 Windows 窗体应用程序( 1.4 小节创建的应用程序就是一个 Windows 窗体应用程序)。控制台应用程序的界面往往比较简单,而 Windows 窗体应用程序能够提供丰富的图形界面。

1 .控制台应用程序2.Windows 窗体应用程序

Page 6: 第 1 章   C# 入门基础

C#从入门到实践

1.2 搭建 Visual Studio 2008 开发环境

本小节介绍搭建开发 C# 应用程序(如 Windows 窗体应用程序、 ASP.NET 网站等)的环境,包括安装 Microsoft Visual Studio 2008 、配置集成开发环境( IDE )、熟悉集成开发环境( IDE )等内容。

注意:笔者机器的操作系统为 Microsoft Windows Server 2003 Enterprise Edition Service Park 2 。

Page 7: 第 1 章   C# 入门基础

C#从入门到实践

1.2.1 安装 Microsoft Visual Studio 2008

下面介绍在笔者机器上安装 Microsoft Visual Studio Team System 2008 简体中文版的操作步骤,具体如下。

Page 8: 第 1 章   C# 入门基础

C#从入门到实践

1.2.2 配置集成开发环境( IDE )

由于 Microsoft Visual Studio 2008 集成开发环境( IDE )非常复杂,为了以后能够更加方便地开发各种 C# 应用程序,在此,特意详细介绍配置 Microsoft Visual Studio 2008集成开发环境的方法。

Page 9: 第 1 章   C# 入门基础

C#从入门到实践

1.2.3 熟悉集成开发环境( IDE )

Microsoft Visual Studio 2008 集成开发环境包括多个可以停靠或浮动的面板,如“工具箱”、“服务器资源管理器”、“解决方案资源管理器”、“属性”等面板。

Page 10: 第 1 章   C# 入门基础

C#从入门到实践

1.3 创建第一个控制台应用程序

本节介绍使用 Microsoft Visual Studio 2008 集成开发环境( IDE )创建第一个控制台应用程序——Sample_01_CA 的方法,以及开发 Sample_01_CA 应用程序所涉及的各种基本技术,如编写 C# 代码、运行应用程序等。

Page 11: 第 1 章   C# 入门基础

C#从入门到实践

1.3.1 创建 Sample_01_CA 控制台应用程序

依次选择“开始” |“所有程序” |“Microsoft Visual Studio 2008”|“Microsoft Visual Studio 2008”命令,打开“起始页 - Microsoft Visual Studio” 对话框。单击“最近项目”面板中的“创建”下的“项目”链接,弹出“新建项目”对话框,如图 1.24所示。

Page 12: 第 1 章   C# 入门基础

C#从入门到实践

1.3.2 解决方案资源管理器

创建 Sample_01_CA 控制台应用程序成功之后, Microsoft Visual Studio 2008 集成开发环境( IDE )将为该应用程序创建一个默认类文件,名称为“ Program.cs” 。打开“解决方案资源管理器”面板,可以查看 Sample_01_CA控制台应用程序包含的所有资源和数据,如图 1.25所示。

Page 13: 第 1 章   C# 入门基础

C#从入门到实践

1.3.3 Program.cs文件

双击“解决方案资源管理器”面板中的“ Program.cs” 节点,打开 Program.cs文件。该文件为 Sample_01_CA 控制台应用程序提供主入口点。

Page 14: 第 1 章   C# 入门基础

C#从入门到实践

1.3.4 AssemblyInfo.cs文件

首先展开“解决方案资源管理器”面板中的“ Properties”节点,然后双击“ AssemblyInfo.cs” 节点打开AssemblyInfo.cs文件。该文件用来配置 Sample_01_CA控制台应用程序的程序集信息。

Page 15: 第 1 章   C# 入门基础

C#从入门到实践

1.3.5 运行应用程序

按下“ F5”按钮或者单击Microsoft Visual Studio 2008 集成开发环境中的按钮即可运行 Sample_01_CA 控制台应用程序。该应用程序运行之后,显示一个黑色的控制台对话框,如图 1.26所示。

Page 16: 第 1 章   C# 入门基础

C#从入门到实践

1.4 创建第一个 Windows 窗体应用程序

本节介绍使用 Microsoft Visual Studio 2008 集成开发环境( IDE )创建第一个 Windows 窗体应用程序——Sample_01_WFA 的方法,以及开发 Sample_01_WFA 应用程序所涉及的各种基本技术,如设计 Windows 窗体、编写 C# 代码、配置应用程序、运行应用程序等。

Page 17: 第 1 章   C# 入门基础

C#从入门到实践

1.4.1 创建 Sample_01_WFA Windows 窗体应用程序

依次选择“开始” |“所有程序” |“Microsoft Visual Studio 2008”|“Microsoft Visual Studio 2008”命令,打开“起始页 - Microsoft Visual Studio” 对话框。单击“最近项目”面板中的“创建”下的“项目”链接,弹出“新建项目”对话框,如图 1.27所示。

Page 18: 第 1 章   C# 入门基础

C#从入门到实践

1.4.2 解决方案资源管理器

创建 Sample_01_WFA Windows 窗体应用程序成功之后, Microsoft Visual Studio 2008 集成开发环境( IDE)将为该应用程序创建一个默认Windows 窗体,名称为“ Form1.cs” 。打开“解决方案资源管理器”面板,可以查看 Sample_01_WFA Windows 窗体应用程序包含的所有资源和数据,如图 1.28所示。

Page 19: 第 1 章   C# 入门基础

C#从入门到实践

1.4.3 Form1.cs 窗体

在“解决方案资源管理器”面板中双击“ Form1.cs” 节点,打开 Form1.cs 窗体的设计界面,如图 1.29所示。此时,开发人员可以直接将“工具箱”面板中的控件拖放到“ Form1.cs” 窗体上。

Page 20: 第 1 章   C# 入门基础

C#从入门到实践

1.4.4 Form1.Designer.cs文件

首先展开“解决方案资源管理器”面板中的“ Form1.cs” 节点,然后双击“ Form1.Designer.cs” 节点打开Form1.Designer.cs文件。该文件中的代码为 Form1.cs 窗体的设计代码,用来描述 Form1.cs 窗体上的每一个控件。

Page 21: 第 1 章   C# 入门基础

C#从入门到实践

1.4.5 Form1.cs 窗体的代码

右击“解决方案资源管理器”面板中的“ Form1.cs” 节点,打开 Form1.cs 窗体的代码文件。该文件保存 Form1.cs 窗体的事件等设计代码。

Page 22: 第 1 章   C# 入门基础

C#从入门到实践

1.4.6 Program.cs文件

双击“解决方案资源管理器”面板中的“ Program.cs” 节点,打开 Program.cs文件。该文件为 Sample_01_WFA Windows 窗体应用程序提供主入口点。

Page 23: 第 1 章   C# 入门基础

C#从入门到实践

1.4.7 AssemblyInfo.cs文件

首先展开“解决方案资源管理器”面板中的“ Properties”节点,然后双击“ AssemblyInfo.cs” 节点打开AssemblyInfo.cs文件。该文件用来配置 Sample_01_WFA Windows 窗体应用程序的程序集信息。

Page 24: 第 1 章   C# 入门基础

C#从入门到实践

1.4.8 运行应用程序

按下“ F5”按钮或者单击Microsoft Visual Studio 2008 集成开发环境中的“”按钮即可运行 Sample_01_WFA Windows 窗体应用程序。该应用程序运行之后,显示的第一个对话框为“ Form1” 对话框,如图 1.30所示。

Page 25: 第 1 章   C# 入门基础

C#从入门到实践

1.5 小结

本章主要介绍了搭建开发 Visual Studio 2008 集成开发环境,以及 C# 语言和 .NET Framework 的概述。其中,读者要着重掌握使用 Visual Studio 2008 集成开发环境开发第一个控制台应用程序和 Windows 窗体应用程序的方法。只有这样,才能进行后续的开发。下一章将要介绍使用C# 语言如何编写第一个应用程序。

Page 26: 第 1 章   C# 入门基础

C#从入门到实践

1.6 习题

1 .在本章介绍的 Sample_01_WFA Windows 窗体应用程序之上,实现以下功能。

( 1 )添加名称为“ Dialog.cs” 的窗体到应用程序中。( 2 )运行该应用程序。

Page 27: 第 1 章   C# 入门基础

C#从入门到实践

第 2 章 C# 基本概念

C# 语言从 1.0 版本发展到 3.0 版本经历了比较长的时间,现在已经是一种比较完善、简单、易学的编程语言。为了读者能够首先对 C# 语言有一个简单的认识,笔者特意在本章介绍了 Hello World 应用程序和 C# 语言的一些常见的基本概念,主要介绍以下知识点。

创建 Hello World 应用程序; 编译 Hello World 应用程序; 运行 Hello World 应用程序; C# 程序的概念扩展。

Page 28: 第 1 章   C# 入门基础

C#从入门到实践

2.1 创建 Hello world 应用程序

对于 C#初学者而言, Hello world 应用程序是 C# 语言入门最好的、简单的示例程序。该程序可以在控制台中显示“ Hello world”字符串。下面介绍书写该程序的基本方法。

Page 29: 第 1 章   C# 入门基础

C#从入门到实践

2.1.1 创建 hello.txt文本文件

为了方便初学者真正认识 C# 程序,我们这里不使用集成开发环境来编写本程序,而是使用记事本来编写程序。新建一个名称为“ hello.txt” 的文本文件,并打开该文件。

Page 30: 第 1 章   C# 入门基础

C#从入门到实践

2.1.2 创建 HelloWorld 类

任何一个 C# 应用程序都是由类( class )组成。一个 C# 应用程序可以包括一个类或多个类。类实际上是对某种类型的对象定义变量和方法的原型。它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象程序设计( Object-Oriented Programming ,简称为 OOP )的基础。

面向对象程序设计指一种程序设计范型,它将对象作为程序的基本单元。在面向对象程序设计中,最为基本的概念是类( class )和对象( object ),对象又称为实例。

1 .类2 .对象

Page 31: 第 1 章   C# 入门基础

C#从入门到实践

2.1.3 添加Main() 方法

一旦创建一个类之后,但是不为该类添加任何成员,那么该类就是一个空类,即它不能描述世界上的任何一种对象。为了使得类能够描述一种对象,那么就需要为该类添加一些属性和行为。

一个行为就产生一个动作。在类中,使用方法( method )来描述这一行为。也就是说,方法是一个类能做的事情(即一些计算或操作),但是并没有做这事情。作为一条狗而言,它是会吠叫、会坐下、会吃。因此,为了能够使用Dog 类描述狗,那么就需要在该类中定义以下 3 个方法。

Bark() ,吠叫。 Sit() ,坐下。 Eat() ,吃。

Page 32: 第 1 章   C# 入门基础

C#从入门到实践

2.1.4 调用 WriteLine() 方法

在 Dog 类中,虽然定义了狗的 3 个行为:吠叫、坐下和吃,但是并没有使这 3 个行为发生。如果想要芊芊这一条狗吠叫,那么就需要一个主动的动作使得芊芊吠叫。这一个主动的动作就是调用该行为对应的方法,即通过调用方法使得该方法对应的行为发生。

Page 33: 第 1 章   C# 入门基础

C#从入门到实践

2.1.5 引入 System命名空间

世界上存在很多狗,而且一些狗的名字也相同。譬如,张三家的狗叫芊芊,而李四家的狗也叫芊芊。那么如何区分这两家的狗呢?自然,称呼张三家的狗可能是“张三家的芊芊”,称呼李四家的狗可能是“李四家的芊芊”。通过这种方式,就能够区分张三家和李四家的芊芊了。

Page 34: 第 1 章   C# 入门基础

C#从入门到实践

2.1.6 整理Hello world 应用程序的代码

经过上述步骤之后,就已经书写了一个完整的 C# 应用程序—— Hello world 应用程序,它的完整的程序代码如下。

using System;

class HelloWorld

{

static void Main()

{

Console.WriteLine("Hello, World");

}

}

Page 35: 第 1 章   C# 入门基础

C#从入门到实践

2.2 编译和运行 Hello World 应用程序

2.1 小节仅仅书写了 Hello world 应用程序的代码。如果要将这一段程序代码成为一个可以执行的文件,则需要使用Microsoft C# 编译器编译这一段代码。

(源码网整理: www.codepub.com)

Page 36: 第 1 章   C# 入门基础

C#从入门到实践

2.3 C# 程序的概念扩展

在 2.1 小节中介绍了 C# 面向对象程序设计的一些基本概念,如类、对象、实例、属性、方法、调用方法等。除了上述这些概念之外,还有一些比较常用的概念,如继承性、多态性等。

1 .继承性2 .多态性3 .接口

Page 37: 第 1 章   C# 入门基础

C#从入门到实践

2.4 小结

本章主要介绍了“ Hello world” 应用程序,包括创建 Hello World 应用程序、编译 Hello World 应用程序、运行Hello World 应用程序和分析 Hello World 应用程序。其中,读者需要着重掌握使用记事本创建 Hello World 应用程序的方法。下一章将介绍 C# 的类型。

Page 38: 第 1 章   C# 入门基础

C#从入门到实践

2.5 习题

使用记事本撰写一个名称为“ Test_02”的 C# 应用程序的代码,并将此代码编译为一个名称为“ Test_02.exe” 的可执行文件。 Test_02 应用程序在控制台显示“ This is a C# program.”字符串。

Page 39: 第 1 章   C# 入门基础

C#从入门到实践

第 3 章 类型

类型是 C# 语言中最为基本的概念之一。不同类型的变量将拥有不同的数据存储方式和操作方法。 C# 语言的类型系统是统一的,它可以把任何类型的值都按照对象来处理。本章将讲解 C# 语言中各种类型,主要介绍以下知识点

值类型;引用类型; 装箱;拆箱。

Page 40: 第 1 章   C# 入门基础

C#从入门到实践

3.1 类型概述

C# 语言中的每一个类型都直接或间接派生于 object 类型,即 object 类型是 C# 语言所有类型的最终基类型。 C# 语言的类型可以分为以下 3 种类型。

值类型( value-type ),它的变量直接包含其数据。引用类型( reference-type ),它的变量只存储对其数据

的引用(即访问其数据的访问地址)。引用类型的变量又称为对象( object )。

指针类型( point-type ),和 C、 C++ 语言中的指针类似,而且只能用作在不安全代码中。由于在 C# 编程中很少使用指针类型,因此,在此不做详细介绍。

Page 41: 第 1 章   C# 入门基础

C#从入门到实践

3.2 值类型

值类型要么是结构类型,要么是枚举类型。值类型的变量直接包含其数据,而且其值不可能为 null 。在操作值类型的变量时,只会影响该变量的数据,而不会影响另外一个变量的值。所有的值类型都直接或间接派生于System.ValueType 类型。

值类型包括结构类型、枚举类型、布尔类型、自定义结构类型、 sbyte、 byte、 char、 short、 ushort、 int、 uint、 long、 ulong、 float、 double和 decimal 类型。其中, C# 语言提供了一种被称为“简单类型( simple type )”的预定义结构类型。这些类型通过 C#保留字标识,如char、 int 等。本节将详细介绍值类型的知识点。

Page 42: 第 1 章   C# 入门基础

C#从入门到实践

3.2.1 System.ValueType 类型

所有值类型都直接或间接从 System.ValueType 类隐式继承而来,并且任何类型不能从值类型派生而来。 System.ValueType 本身是一个类,它只包含以下 3个方法。

Equals() ,判定当前实例与指定的对象是否相等。 GetHashCode() ,返回当前实例的哈希代码。该哈希代码

用于哈希表(一种数据结构)的散列运算。 ToString() ,返回当前实例的完全限定类型名称。

Page 43: 第 1 章   C# 入门基础

C#从入门到实践

3.2.2 整数类型整数类型包括 9 种类型,如 sbyte、 byte、 short 等。它们的具体说明、 .NET Framework 中的名称和取值范围如表 3.1所示。1. int 类型2. long 类型3. char 类型类型 描述 .NET Framework中的名称 取值范围

sbyte 有符号 8位整数 System.SByte -128~127

byte 无符号 8位整数 System.Byte 0~255

short 有符号 16位整数 System.Int16 -32768~32767

ushort 无符号 16位整数 System.UInt16 0!65535

int 有符号 32位整数 System.Int32 -2147483648~2147483647

uint 无符号 32位整数 System.UInt32 0~4294967295

long 有符号 64位整数 System.Int64 -9223372036854775808~9223372036854775807

ulong 无符号 64位整数 System.UInt64 0~18446744073709551615

char 无符号 16位整数 System.Char 0~65535, 16位的 Unicode字符。

Page 44: 第 1 章   C# 入门基础

C#从入门到实践

3.2.3 浮点型

C# 语言包括两种浮点型: float和 double。 float 类型表示32位的单精度浮点数,它的取值范围为 ±1.5e-45~±3.4e38。 double 类型表示 64位的双精度浮点数,它的取值范围为 ±5.0e-324~±1.7e308 。浮点数包括以下3 种特殊的值。

正零和负零正无穷大和负无穷大非数字( Not-a-Number )值

Page 45: 第 1 章   C# 入门基础

C#从入门到实践

3.2.4 decimal 类型

decimal 类型表示 128位的数值,取值范围为 ±1.0e-28~±7.9e28 ,特别适用于财务计算和货币计算。和 float类型一样,在书写 decimal 类型的值时,需要在数值后添加后缀m ,否则编译出错。

与浮点型相比, decimal 类型具有较高的精度,但取值范围较小。因此,从浮点型到 decimal 类型的转换可能会产生溢出异常,而从 decimal 类型到浮点型的转换则可能导致精度损失。正是由于这些原因,所以,在浮点型和decimal 类型之间不存在隐式转换。如果要转换浮点型到decimal 类型,则必须使用强制转换方法。

Page 46: 第 1 章   C# 入门基础

C#从入门到实践

3.2.5 bool 类型

bool 类型表示布尔逻辑量。它只包含两个值: true和 false,而且这两个值意义恰好相反。

Page 47: 第 1 章   C# 入门基础

C#从入门到实践

3.2.6 枚举类型

枚举( enum )类型也是一种值类型,它具有命名常量的独特的类型。每个枚举类型都有一个基础类型,该基础类型必须为byte、 sbyte、 short、 ushort、 int、 uint、 long或ulong 。其中,默认的基础类型为 int 。

枚举类型一般包含一个或多个枚举值,每一个枚举值之间用逗号( , )分隔。枚举值又称为枚举数,它的默认基础类型为 int 。默认情况下,第一个枚举数的值为 0 ,后面的每一个枚举数的值依次增 1 。

Page 48: 第 1 章   C# 入门基础

C#从入门到实践

3.2.7 结构类型

结构类型也是一种值类型,它可以声明常量、字段、方法、属性、索引器、运算符、实例构造函数、静态构造函数和嵌套类型。有关结构类型的知识点将在第 9 章中进行详细介绍。

Page 49: 第 1 章   C# 入门基础

C#从入门到实践

3.2.8 实例一:把整数转换为二进制数

【实例 3-1】实现把整数转换为二进制数的功能。该功能由ConvertIntToBinary(int n)静态函数实现, n参数表示被转换的整数,该函数返回二进制数的字符串形式。

Page 50: 第 1 章   C# 入门基础

C#从入门到实践

3.2.9 实例二:把二进制数转换为整数

【实例 3-2】实现把二进制数转换为整数的功能。该功能由ConvertBinaryToInt(string binary)静态函数实现, binary参数表示被转换的二进制数的字符串形式,该函数返回一个整数。

Page 51: 第 1 章   C# 入门基础

C#从入门到实践

3.3 引用类型

引用类型主要包括 6 种类型: object 类型、 string 类型、类类型、数组类型、接口类型和委托类型。引用类型变量的值是对该类型的某个实例的一个引用。其中,类型的实例被称为对象。在引用类型中,存在一个很特殊的值: null。 null 能够兼容所有的引用类型,表示“每一被引用的实例”。本节将详细介绍引用类型的知识点。

Page 52: 第 1 章   C# 入门基础

C#从入门到实践

3.3.1 对象类型

对象( object )类型是 C# 类型系统中所有其他类型的最终基类。 C# 中的每种类型都是直接或间接从 object 类类型派生的。因此, C# 中的任何类型都可以转换为 object 类型。

Page 53: 第 1 章   C# 入门基础

C#从入门到实践

3.3.2 字符串类型

字符串( string )类型是直接从 object继承而来的类类型,它对应着 .NET Framework 中的 System.String 类型。

Page 54: 第 1 章   C# 入门基础

C#从入门到实践

3.3.3 类类型

类( class )类型是 C# 中最常用的类型。它是一个数据结构,能够定义数据成员、函数成员和嵌套类型等内容。其中,数据成员包括常量和字段,函数成员包括方法、属性、事件、索引器、运算符、实例构造函数、析构函数和静态构造函数。

特别地,类类型还支持一种被称为“继承”的机制。继承是指派生类可用来扩展和专门化基类的一种机制。有关类类型的知识点将在第 8 章中进行详细介绍。

Page 55: 第 1 章   C# 入门基础

C#从入门到实践

3.3.4 数组类型

数组( Array )是一种数据结构,它可以将多个类型相同的元素组合为一个整体,从而通过数组统一访问或操作这些元素。数字可以通过计算索引来访问数组中的每一个元素。每一个元素的类型称为数字的元素类型。

Page 56: 第 1 章   C# 入门基础

C#从入门到实践

3.3.5 接口类型

接口( interface )类型和类类型非常相似。它也是一个数据结构,能够声明数据成员和函数成员。其中,数据成员主要包括属性,函数成员包括方法和事件。

Page 57: 第 1 章   C# 入门基础

C#从入门到实践

3.3.6 委托类型

委托( delegate )也是一种数据结构,它能够引用一个或多个方法。特别地,对于实例方法,它还能够引用这些方法所对应的对象实例。读者如果熟悉 C++ 中的函数指针,那么就不难理解委托这一概念了。

委托类型类似于 C++ 中的函数指针,但是它是类型安全的。委托类型能够将方法作为参数进行传递,并且还可以定义回调方法。

Page 58: 第 1 章   C# 入门基础

C#从入门到实践

3.4 装箱和拆箱

引用类型总是分配在托管堆上,而值类型总是分配在堆栈上。有时,程序需要获取指向值类型的引用。此时,需要将值类型转换为引用类型,这一操作被称为装箱。反之,把引用类型转换为值类型称为拆箱。

装箱和拆箱是 C# 的类型系统中两个很重要的概念,它在值类型和引用类型之间的架起了一座桥梁。通过装箱和拆箱操作,可以将任何值类型的变量的值转换为引用类型的变量的值。反之,也可以进行转换。特别地,有了装箱和拆箱操作,就可以将 C# 类型系统中的任何类型的值最终都可以按对象来处理。

Page 59: 第 1 章   C# 入门基础

C#从入门到实践

3.4.1 装箱

装箱是指将值类型隐式转换为引用类型。对于值类型而言,装箱的具体操作为:首先分配一个对象实例,然后将值类型的值复制到该实例中。装箱前后不是同一个实例。对于引用类型而言,装箱前后都共享同一个实例。

Page 60: 第 1 章   C# 入门基础

C#从入门到实践

3.4.2 拆箱

拆箱是指将引用类型隐式转换为值类型。拆箱的具体操作包括以下 2 个步骤。

( 1 )检查该对象实例是否为给定值类型的一个装了箱的值。

( 2 )将值从实例中复制出来。

Page 61: 第 1 章   C# 入门基础

C#从入门到实践

3.5 小结

本章主要介绍了 C# 语言的类型系统的基础知识,如值类型、引用类型、类型转换、装箱、拆箱等。其中,读者要着重掌握值类型和引用类型,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的变量。

Page 62: 第 1 章   C# 入门基础

C#从入门到实践

3.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_03” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个整型变量 vint 和一个字符串变量 vstring ,将 vint变量转换为字符串,将 vstring变量转换为一个整数。

Page 63: 第 1 章   C# 入门基础

C#从入门到实践

第 4 章 变量

变量是 C# 语言中最为基本的概念之一,它表示存储位置。每一个变量的值由其类型确定。本章将讲解 C# 语言中各种变量,主要介绍以下知识点。

变量概述;变量分类;变量赋值; 使用值参数传递数据; 使用 ref参数传递数据; 使用 out参数传递数据;变量转换。

Page 64: 第 1 章   C# 入门基础

C#从入门到实践

4.1 变量概述

在 C# 语言中,变量表示存储位置。每一个变量都具有一个类型,该类型确定变量存储的内容。对于两个变量而言,如果它们的值相同,但是类型不同,那么该变量存储的值是不相同的。

声明一个变量之后,该变量可能具有初始值,也可能不具有初始值。如果变量具有初始值,则称之为初始已赋值( initially assigned )。如果变量不具有初始值,则称之为初始未赋值( initially unassigned )。

如果是第一次明确指定变量的值,则称之为变量的初始化。如果是初始未赋值变量,必须经过初始化之后,才能够被使用。

Page 65: 第 1 章   C# 入门基础

C#从入门到实践

4.2 变量分类

C# 语言定义了 7 种不同类别的变量:静态变量、实例变量、数组元素、值参数、引用参数、输出参数和局部变量。本小节将详细介绍这 7 种类别的变量。

Page 66: 第 1 章   C# 入门基础

C#从入门到实践

4.2.1 静态变量

静态变量( static variable )是指使用 static修饰符声明的变量。静态变量总是在包含了它的那个类型的静态构造函数(第 8 章)执行之前就存在了,在关联的应用程序域终止时终止。

Page 67: 第 1 章   C# 入门基础

C#从入门到实践

4.2.2 实例变量

实例变量( instance variable )和静态变量相对应。实例变量是指未使用 static修饰符声明的变量。实例变量包括两种类型的变量:类的实例变量和结构的实例变量。

1 .类的实例变量2 .结构的实例变量

Page 68: 第 1 章   C# 入门基础

C#从入门到实践

4.2.3 局部变量

顾名思义,局部变量( local variable )是在应用程序的某一段时间内存在。局部变量可以声明在块( block )、 for语句、 switch 语句和 using 语句中,即局部变量是通过“ local-variable-declaration” 来声明的。

Page 69: 第 1 章   C# 入门基础

C#从入门到实践

4.2.4 值参数

对于一个函数成员而言,它都存在一个参数列表(紧跟在函数成员名称之后的小括弧中)。当然,该参数列表可以是空,也可以包含一个或多个参数,多个参数之间使用逗号( , )分隔。

在声明参数时,可以不使用修饰符,也可以使用 ref或 out修饰符。值参数( value parameter )是指未使用 ref或out修饰符声明的参数。

Page 70: 第 1 章   C# 入门基础

C#从入门到实践

4.2.5 ref参数

引用参数( reference parameter )是值使用 ref修饰符声明的参数。引用参数和值参数最大的一个区别在于:在函数成员中,函数成员为值参数分配了一个新的存储位置,而引用参数仍然使用其基础变量的存储位置。即引用参数和其基础变量操作了同一个变量,而值参数和其基础变量是操作了两个不同变量,而且不互相影响。

Page 71: 第 1 章   C# 入门基础

C#从入门到实践

4.2.6 out参数

输出参数( output parameter )是值使用 out修饰符声明的参数。输出参数和值参数最大的一个区别在于:在函数成员中,函数成员为值参数分配了一个新的存储位置;输出参数不创建新的存储位置,而是使用基础变量的存储位置。因此,输出参数的值总是与基础变量相同。

简而言之,基础变量实际上是分配了一个存储位置,在调用包含 out参数的函数成员时,该函数成员将在这一个存储位置存储新的值,并修改基础变量的值。

Page 72: 第 1 章   C# 入门基础

C#从入门到实践

4.2.7 数组元素

数组元素是指作为函数成员参数的数组(第 8 章)的元素,它总是在创建数组实例时开始存在,在没有对该数组实例的引用时停止存在。每个数组元素的初始值都是其数组元素类型的默认值。

Page 73: 第 1 章   C# 入门基础

C#从入门到实践

4.3 变量赋值

变量赋值是指给变量指定某一个明确的值,如“ int i = 2008;” 语句在声明 i变量的同时给该变量赋值为 2008 。在函数成员可执行代码中的给定位置,如果编译器可确定变量已自动初始化或已成为至少一个赋值的目标,则称该变量已明确赋值( definitely assigned )。

Page 74: 第 1 章   C# 入门基础

C#从入门到实践

4.4 实例一:使用值参数传递数据

【实例 4-1】演示了使用值参数传递数据的方法。该功能由static int CountSum(int i,int j)静态函数实现, i和 j参数均为值参数。 CountSum(int i,int j)函数返回 i和 j参数的值增 1之后的和。

Page 75: 第 1 章   C# 入门基础

C#从入门到实践

4.5 实例二:使用 ref参数传递数据

【实例 4-2】演示了使用 ref参数传递数据的方法。该功能由 static int RefCountSum(ref int i,ref int j)静态函数实现, i和 j参数均为 ref参数。 RefCountSum(ref int i,ref int j)函数返回 i和 j参数的值增 1之后的和。

Page 76: 第 1 章   C# 入门基础

C#从入门到实践

4.6 实例三:使用 out参数返回数据

【实例 4-3】演示了使用 out参数传递数据的方法。该功能由 static void OutCountSum(int i,int j,out int sum)静态函数实现, i和 j参数均为的值参数, sum参数为 out参数。 OutCountSum(int i,int j,out int sum)函数本身不返回值,但是用 sum参数保存 i和 j参数的值增 1之后的和。

Page 77: 第 1 章   C# 入门基础

C#从入门到实践

4.7 变量转换

转换( conversion )使一种类型的表达式可以被视为另一种类型。变量转换( variable conversion )使一种类型的变量可以被视为另一种类型。转换可以分为隐式转换( implicit conversion )和显式转换( explicit conversion)。如果在转换时,需要添加强制转换的类型,那么该转换为显式转换。本小节将介绍变量转换的知识点。

Page 78: 第 1 章   C# 入门基础

C#从入门到实践

4.7.1 隐式转换

隐式转换是指不需要添加强制转换的类型的转换。常用的隐式转换包括以下几种。

标识转换,在同一类型内进行转换,它能够使已具有所需类型的实体可被认为是可转换的。

隐式数值转换,如从 int 类型转换为 long 类型等。隐式枚举转换,将数值转换为枚举类型。隐式引用转换,如引用类型转换为 object 类型等。 装箱转换,如值类型转换为 object 类型等。隐式常量表达式转换,如将 int 类型转换为 uint 类型等。 用户定义的隐式转换,包括以下 3 个步骤:一个标准的隐

式转换;执行用户定义的隐式转换运算符;另一个标准的隐式转换。

Page 79: 第 1 章   C# 入门基础

C#从入门到实践

4.7.2 显示转换

显式转换是指需要添加强制转换的类型的转换。常用的显式转换包括以下几种。

显式数值转换,如 long 类型转换为 int 类型等。显式枚举转换,如 int 类型转换为枚举类型等。显式引用转换,如 object 类型转换为引用类型等。显式接口转换,如 object 类型转换为接口类型等。拆箱转换,如 object 类型转换为值类型等。 用户定义的显式转换 , 包括以下 3 个步骤:一个标准的隐

式转换;执行用户定义的显式转换运算符;另一个标准的隐式转换。

Page 80: 第 1 章   C# 入门基础

C#从入门到实践

4.8 小结

本章主要介绍了 C# 语言中的变量的基础知识,如变量概述、变量分类、变量赋值、值参数、 ref参数、 out参数、变量转换等。其中,读者要着重掌握变量赋值、值参数、 ref参数、 out参数和变量转换,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的表达式和运算符。

Page 81: 第 1 章   C# 入门基础

C#从入门到实践

4.9 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_04” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ ValueF” 的方法,且该方法使用值参数 value 。

( 3 )创建一个名称为“ RefF” 的方法,且该方法使用 ref参数 value 。

( 4 )创建一个名称为“ OutF” 的方法,且该方法使用 out参数 value 。

Page 82: 第 1 章   C# 入门基础

C#从入门到实践

第 5 章 表达式和运算符

表达式是 C# 语言组成的重要元素之一,它是可以计算且结果为单个值、对象、方法或命名空间的代码片段。表达式也可以包含文本值、方法调用、运算符及其操作数,或简单名称。简单的说,表达式是一个由操作数和运算符组成的序列。本章将讲解 C# 语言中的表达式和运算符,主要介绍以下知识点。

表达式分类; this、 base和 new 关键字; 运算符; 运算检查; 运算符重载。

Page 83: 第 1 章   C# 入门基础

C#从入门到实践

5.1 表达式

表达式是一个由操作数( operand )和运算符( operator )构成的序列。运算符指定操作数的运算规则,即指示对表达式中的操作数进行什么样的运算。本节将介绍表达式的知识点。

Page 84: 第 1 章   C# 入门基础

C#从入门到实践

5.1.1 表达式分类

在 C# 语言中,可以把表达式分为以下 9 种类别,如表 5.1所示。

表达式类型 说明值 每一个值都有关联的类型。变量 每一个变量都有关联的类型。如果该变量存在了相关的类型,

则称该变量为已声明类型的变量。命名空间 C#程序是利用命名空间组织起来的。类型 指定变量数据的存储方式和操作方法。方法组 表示一组方法,并可以通过实例调用方法组中的方法。属性访问 每个属性访问都有关联的类型,即该属性的类型。事件访问 每个事件访问都有关联的类型,即该事件的类型。索引器访问 每个索引器访问都有关联的类型,即该索引器的元素类型。Nothing 出现在调用一个具有 void返回类型的方法时。

Page 85: 第 1 章   C# 入门基础

C#从入门到实践

5.1.2 this 关键字

this 关键字可以用来引用类的当前实例,还可以用作扩展方法的第一个参数的修饰符。 this 关键字存在以下 3 种常用用法。

1 .限定名称相同的成员2 .将对象本身作为参数3 .声明索引器

Page 86: 第 1 章   C# 入门基础

C#从入门到实践

5.1.3 base 关键字

base 关键字用于从派生类中访问基类的成员,主要存在以下2 种用法。

调用基类上已被其他方法重写的方法。指定创建派生类实例时应调用的基类构造函数。base 关键字之后一般跟着“ .” 标记和一个标识符或一个用

方括号括起来的表达式列表。

Page 87: 第 1 章   C# 入门基础

C#从入门到实践

5.1.4 new 关键字

new 关键字可以作为 new 运算符、 new修饰符或 new约束。

1. new 运算符2. new修饰符3. new约束

Page 88: 第 1 章   C# 入门基础

C#从入门到实践

5.2 运算符

运算符是表达式很重要的一部分,它指示对表达式中的操作数进行什么样的运算,如 +、 - 、 *、 /、% 等。根据运算符所需操作数的个数,可以把运算符分为以下 3 类。本节介绍运算符的知识点。

一元运算符,只带有一个操作数并使用前缀表示法(如 --x )或后缀表示法(如 x++ ),如 ++、 -- 等运算符。

二元运算符,带有两个操作数并且全都使用中缀表示法(如 x+y ),如 +、 - 、 *、 / 等运算符。

三元运算符,带有 3 个操作数并使用中缀表示法,如 ?: 运算符。

Page 89: 第 1 章   C# 入门基础

C#从入门到实践

5.2.1 运算符优先级

算术表达式是最为常见的一种表达式。它由操作数和运算符组成,而且这些运算符之间是存在一定优先级的,如 * 运算符的优先级就大于 + 运算符的优先级。 C# 语言中的运算符一样,也存在优先级。在计算表达式的值时,也必须遵循运算符的优先级的规则。

Page 90: 第 1 章   C# 入门基础

C#从入门到实践

5.2.2 一元运算符

+、 -、 !、 ~、 ++x、 --x和 (T)x被称为一元运算符。其中, (T)x 运算符为强制转换运算符,它可以将一种类型转换为另外一种类型。 +、 -和 ~ 运算符分别表示一元加运算、一元减运算和按位求补运算。下面详细介绍 !、 ++x、 --x和 (T)x 运算符的使用方法。

1. ++ 运算符2. -- 运算符3. ! 运算符4. (T)x 运算符

Page 91: 第 1 章   C# 入门基础

C#从入门到实践

5.2.3 算术运算符

*、 /、%、 +和–运算符称为算术运算符,它们分别表示乘法、除法、余数、加法和减法运算。语法如下。

left expression operator right expression

left expression和 right expression分别表示左操作数和右操作数, operator 表示运算符,可以为 *、 /、%、 +和–。

Page 92: 第 1 章   C# 入门基础

C#从入门到实践

5.2.4 逻辑运算符

&、 ^和 | 运算符称为逻辑运算符。 & 运算符计算两个操作数的按位逻辑 AND, | 运算符计算两个操作数的按位逻辑 OR, ^ 运算符计算两个操作数的按位逻辑 XOR 。语法如下。

left expression operator right expression

left expression和 right expression分别表示左操作数和右操作数, operator 表示运算符,可以为 &、 ^和 | 。

Page 93: 第 1 章   C# 入门基础

C#从入门到实践

5.2.5 条件运算符

?: 运算符称为条件运算符,它是 C# 语言中唯一的一个三元运算符,语法如下。

条件表达式 ? resulta : resultb;

该表达式首先计算条件表达式的值。如果条件表达式的值为真,则 resulta 的值,并成为运算结果。否则计算 resultb,并成为运算结果。

Page 94: 第 1 章   C# 入门基础

C#从入门到实践

5.2.6 条件逻辑运算符

&&和 || 运算符称为条件逻辑运算符。 && 运算符为逻辑与运算符,它计算左右操作数的逻辑与。 || 运算符为逻辑或运算符,它计算左右操作数的逻辑或。语法如下。

left expression operator right expression

left expression和 right expression分别表示左操作数和右操作数, operator 表示运算符,可以为 &&和 || 。

Page 95: 第 1 章   C# 入门基础

C#从入门到实践

5.2.7 移位运算符

<<和 >> 运算符被称为移位运算符。 << 运算符表示左移位, >> 运算符表示右移位。语法如下:

erpression operator count;

expression 表示被移位的表达式, count 表示移动的位数, operator 表示运算符,可以为 <<和 >> 。

Page 96: 第 1 章   C# 入门基础

C#从入门到实践

5.2.8 关系和类型测试运算符

==、 !=、 <、 >、 <=、 >=、 is和 as 运算符称为关系和类型测试运算符。语法如下:

left expression operator right expression

left expression和 right expression分别表示左操作数和右操作数, operator 表示运算符,可以为 ==、 !=、 <、 >、 <=、 >=、 is和 as 。其中, ==、 !=、 <、 >、 <=和 >= 运算符为比较运算符,它们的具体计算方法如下:

x == y ,如果 x 等于 y ,则为 true ,否则为 false 。x != y ,如果 x 不等于 y ,则为 true ,否则为 false 。x < y ,如果 x 小于 y ,则为 true ,否则为 false 。x > y ,如果 x 大于 y ,则为 true ,否则为 false 。x <= y ,如果 x 小于等于 y ,则为 true ,否则为 false 。x >= y ,如果 x 大于等于 y ,则为 true ,否则为 false 。

Page 97: 第 1 章   C# 入门基础

C#从入门到实践

5.2.9 赋值运算符

= 、 *=、 /=、%=、 +=、 -=、 <<=、 >>=、&=、 ^=和 |= 运算符被称为赋值运算符,它们能够为变量、属性、事件或索引器元素赋新值。语法如下:

left expression operator right expression

left expression和 right expression分别表示左操作数和右操作数, operator 表示运算符,如 = 、 *=、 /= 等。

Page 98: 第 1 章   C# 入门基础

C#从入门到实践

5.3 实例一:使用 checked和unchecked 运算符检查运算

【实例 5-1】演示了使用 checked和 unchecked 运算符检查运算的方法。该功能由 static void CheckCompute()静态函数实现。

Page 99: 第 1 章   C# 入门基础

C#从入门到实践

5.4 实例二:复数运算符重载

在 C# 语言中,所有一元和二元运算符都具有可自动用于任何表达式的预定义实现。除了预定义运算操作之外,还可通过在类或结构中设置 operator声明来引入用户定义的运算操作。这一技术被称为运算符重载。注意:用户定义的运算符操作的优先级总是高于预定义运算符操作的优先级。运算符重载可以分为一元运算符重载和二元运算符重载,重载方法如表 5.3所示。

运算符表示法 重载函数表示法 说明op x operator op(x) op为运算符x op operator op(x)  

x op y operator op(x,y)  

Page 100: 第 1 章   C# 入门基础

C#从入门到实践

5.5 小结

本章主要介绍了 C# 语言中的表达式和运算符,如表达式分类、 this 关键字、 base 关键字、 new 关键字、运算符、运算符重载等。其中,读者要着重掌握表达式、运算符和运算符重载,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的语句。

Page 101: 第 1 章   C# 入门基础

C#从入门到实践

5.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_05” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ Sum” 的方法,且在该方法中使用

checked和 unchecked 运算符检查计算两个数的和的运算操作。

Page 102: 第 1 章   C# 入门基础

C#从入门到实践

第 6 章 语句

和其他编程开发语言(如 C、 C++ 等)一样, C# 语言也是由各种各样的语句有序构建而成的。语句可以声明局部变量或常量,调用方法,创建对象,将值赋予变量、属性或字段等。一般地,语句以 ; (分号)终止。本章将讲解C# 语言中的各种语句,主要介绍以下知识点。

基本语句;跳转语句;选择语句; 迭代语句;其他语句。

Page 103: 第 1 章   C# 入门基础

C#从入门到实践

6.1 语句概述

和其他程序开发语言一样, C# 语言也提供了多种语句。 C#语言的语句可以分为以下 3 个大类:

标记语句,给语句加上一个标签作为前缀。声明语句,用来声明局部变量或常量嵌入语句,能够嵌入到本身语句或其他语句中执行的语句

Page 104: 第 1 章   C# 入门基础

C#从入门到实践

6.2 基本语句

C# 语言包含多种常用的基本语句,如空语句、标记语句、表达式语句、声明语句、块等。本节将详细介绍创建这些语句的方法。

Page 105: 第 1 章   C# 入门基础

C#从入门到实践

6.2.1 空语句

顾名思义,空语句( empty statement )不包括任何实际性语句,它什么都不做。空语句的语法形式如下:

;

当在要求有语句的上下文中不执行任何操作时,使用空语句

Page 106: 第 1 章   C# 入门基础

C#从入门到实践

6.2.2 标记语句

标记语句( labeled statement )可以给语句加上一个标签作为前缀,它可以出现在块(第 6.2.5 节)中,但是不允许它们作为嵌入语句。标记语句的语法形式如下:

identifier : statement;

identifier 为标签的名称。在同一个块中,不能存在两个同名的标签,否则会产生编译错误。 statement 表示被标签标记的语句。

Page 107: 第 1 章   C# 入门基础

C#从入门到实践

6.2.3 表达式语句

表达式语句是 C# 语言程序代码中最为常见的一种语句,它用来计算所给定表达式的值,而且由该表达式计算的值将被丢弃。实际上,表达式的值只是一个中间结果。表达式语句包括以下 7 类语句:

赋值表达式,如“ i = 2008;” 等。 调用表达式,如“ Count();” 等。 创建对象表达式,如“ object o = new object();” 等。前缀递减表达式,如“ -- i” 等。前缀递增表达式,如“ ++ i” 等。后缀递减表达式,如“ i --” 等。后缀递增表达式,如“ i ++” 等。

Page 108: 第 1 章   C# 入门基础

C#从入门到实践

6.2.4 声明语句

声明语句用来声明局部变量或常量,它可以出现在块(第6.2.5 节)中,但不允许它们作为嵌入语句使用。声明语句包括声明局部变量语句和声明局部常量语句。声明局部变量语句用来声明一个局部变量。

Page 109: 第 1 章   C# 入门基础

C#从入门到实践

6.2.5 块

块( block )用于编写多条语句,并且可以将整个块看成一个单个语句。块的语法形式如下:

{ statement-list }

statement-list 为一个语句列表,它是可选的。如果不存在statement-list ,则称该块是空的。语句列表是由一个或多个顺序编写的语句组成。

Page 110: 第 1 章   C# 入门基础

C#从入门到实践

6.3 跳转语句

跳转语句( jump statement )用于无条件地转移程序的控制,它包括以下 5 种跳转语句:

break 语句,用于退出直接封闭它所在的 switch (第6.4.2 小节中介绍)、 while (第 6.5.3 小节中介绍)、 do(第 6.5.4 小节中介绍)、 for (第 6.5.1 小节中介绍)或foreach 语句(第 6.5.2 小节中介绍)。

continue 语句,用于开始直接封闭它的 while、 do、 for或 foreach 语句的一次新循环。

return 语句,一般用于函数成员的返回操作,即将控制返回到函数成员的调用方。

throw 语句,用于产生一个异常。 goto 语句,跳转到指定的标签位置。

Page 111: 第 1 章   C# 入门基础

C#从入门到实践

6.3.1 break 语句

break 语句用于退出直接封闭它所在的 switch、 while、 do、 for或 foreach 语句。它的语法形式如下:

break;

注意: break 语句只能用在 switch、 while、 do、 for或foreach 语句中,否则发生编译时错误。

如果 break 语句位于多层嵌套的 switch、 while、 do、 for或 foreach 语句中, break 语句只能应用于最里层的语句。

Page 112: 第 1 章   C# 入门基础

C#从入门到实践

6.3.2 continue 语句

continue 语句用于开始直接封闭它的 while、 do、 for或foreach 语句的一次新迭代。它的语法形式如下:

continue;

注意: continue 语句只能用在 while、 do、 for或 foreach语句中,否则发生编译时错误。

如果 continue 语句位于多层嵌套的 while、 do、 for或foreach 语句中, continue 语句只能应用于最里层的语句。

Page 113: 第 1 章   C# 入门基础

C#从入门到实践

6.3.3 return 语句

return 语句一般用于函数成员的返回操作,即将控制返回到函数成员的调用方。它的语法形式如下:

return expressionopt;

expressionopt 为返回值的表达式,它是一个可选表达式。 return 语句存在以下两种形式:

不带 expressionopt 表达式的 return 语句,只能用在返回类型为 void 的函数成员、属性的 set 访问器(第 8 章)、事件的 add和 remove 访问器(第 8 章)、实例构造函数(第 8 章)、静态构造函数(第 8 章)或析构函数(第 8章)中。

带 expressionopt 表达式的 return 语句,只能用在返回类型不是 void 的函数成员、属性的 get 访问器(第 8章)。 expressionopt 表达式必须能够隐式转换为其所在函数成员的返回类型。

Page 114: 第 1 章   C# 入门基础

C#从入门到实践

6.3.4 throw 语句

throw 语句用来引发一个异常。它的语法形式如下:throw expressionopt;

expressionopt 为返回值的表达式,它是一个可选表达式。和return 语句一样, throw 语句也分为以下两种形式:

不带表达式的 throw 语句,只能用在 catch块(第 6.6.1 节)中,它将重新引发当前正由该 catch块处理的那个异常。

带表达式的 throw 语句,通过 expressionopt 表达式产生异常的值。而且,该异常的值的类型必须为System.Exception 类型或者从 System.Exception 类派生的类型。

Page 115: 第 1 章   C# 入门基础

C#从入门到实践

6.4 选择语句

选择语句是指根据表达式的值从若干个给定的语句中选择一个来执行的语句。选择语句包括 if 语句和 switch 语句。每一个 if 语句的选择支只有 2 个,而每一个 switch 语句的选择支可以为 1 个或多个。本节将详细介绍 if 语句和switch 语句。

Page 116: 第 1 章   C# 入门基础

C#从入门到实践

6.4.1 if 语句

if 语句能够根据布尔表达式的值选择要执行的语句,它存在以下 2 种语法形式。

if(布尔表达式 ) 嵌入语句 ;

if(布尔表达式 ) 嵌入语句 1; else嵌入语句 2;

布尔表达式

嵌入语句false

true

布尔表达式

嵌入语句1 嵌入语句2

falsetrue

Page 117: 第 1 章   C# 入门基础

C#从入门到实践

6.4.2 switch 语句

switch 语句比 if 语句更加灵活,它可以存在 1 个或多个可执行的选择支。它的语法形式如下:

switch( 表达式 )

{

case 常量表达式 1: 语句块 1;

case 常量表达式 2: 语句块 2;

default: 语句块 n;

}

语句块1 语句块2 语句块n...

表达式的值等于常量表达式1的值

表达式

表达式的值等于常量表达式2的值

表达式的值不等于常量表达式1~n中的任何一个的值

Page 118: 第 1 章   C# 入门基础

C#从入门到实践

6.5 迭代语句

迭代语句是指可以重复执行嵌入语句的语句,包括 for 语句、 foreach 语句、 while 语句和 do 语句。本节将详细介绍这 4 中迭代语句。

Page 119: 第 1 章   C# 入门基础

C#从入门到实践

6.5.1 for 语句

for 语句首先计算一个初始化表达式序列,然后,当某个条件为真时,重复执行相关的嵌入语句并计算一个迭代表达式序列。 for 语句的语法形式如下:

for (初始化表达式 ; 条件表达式 ; 迭代表达式 ) 嵌入语句 ;

条件表达式

嵌入语句false

true

Page 120: 第 1 章   C# 入门基础

C#从入门到实践

6.5.2 foreach 语句

foreach 语句用于枚举一个集合的元素,并对该集合中的每个元素执行一次相关的嵌入语句。 foreach 语句的语法形式如下:

foreach ( 类型 迭代变量 in 表达式 ) 嵌入语句 ;

是否是expression的最后一个元素

嵌入语句true

false

Page 121: 第 1 章   C# 入门基础

C#从入门到实践

6.5.3 while 语句

while 语句能够按照不同条件执行一个嵌入语句零次或多次,它的语法形式如下:

while (布尔表达式 ) 嵌入语句 ;

布尔表达式

嵌入语句false

true

Page 122: 第 1 章   C# 入门基础

C#从入门到实践

6.5.4 do 语句

do 语句和 while 语句非常相似,它能够按照不同条件执行一个嵌入语句一次或多次。它的语法形式如下:

do 嵌入语句 while (布尔表达式 );

如果布尔表达式的值为 true ,则执行嵌入语句。 do 语句按照如下规则执行,执行的流程图如图 6.7所示。

布尔表达式

嵌入语句true

false

Page 123: 第 1 章   C# 入门基础

C#从入门到实践

6.6 其他语句

其他语句主要包括 try 语句、 using 语句、 lock 语句、 checked 语句、 unchecked 语句等。本节将详细介绍这些语句的使用方法。

Page 124: 第 1 章   C# 入门基础

C#从入门到实践

6.6.1 try 语句

try 语句提供一种机制,可以用来捕捉在块的执行期间发生的各种异常。此外, try 语句还能指定一个代码块,并保证当控制离开 try 语句时,总是先执行该代码。

一个 try 语句可能包含 try块、 catch块和 finally块。 try块一般包含需要恢复或清理操作的代码,即有可能发生异常的代码。 catch块一般包括出现异常时需要执行的响应代码。 finally块一般包括确保一定执行的代码,如资源清理操作等。

对于一个 try 语句而言, try块是必须的,而且只能是一个, catch块和 finally块不是必须的。一个 try 语句存在以下 3种形式:

一个 try块,后跟一个或多个 catch块。 一个 try块,后跟一个 finally块。 一个 try块,后跟一个或多个 catch块,后面再跟一个 finally块。

Page 125: 第 1 章   C# 入门基础

C#从入门到实践

6.6.2 using 语句

using 语句用来定义一个范围,并在该范围之外释放一个或多个对象,即用于获取一个或多个资源,并执行一个语句,然后释放该资源。它的语法形式如下:

using (resource-acquisition) embedded-statement

resource-acquisition 用于获取一个或多个资源,表示该资源的对象必须实现了 System.IDisposable 的类或结构。 embedded-statement 为一个嵌入语句,当 using 语句获取其资源之后,将执行该嵌入语句。

执行 using 语句时,一般包括 3 个步骤:获取资源、使用资源和释放资源。 using 语句最常见的形式如下所示。

using (ResourceType resource = expression) statement

Page 126: 第 1 章   C# 入门基础

C#从入门到实践

6.6.3 lock 语句

lock 语句用于首先获取某个给定对象的互斥锁,即对该对象进行加锁。然后执行一个语句,最后释放该锁。它的语法形式如下:

lock (expression) embedded-statement

expression 表示被加锁的对象,且必须为引用类型的对象;embedded-statement 表示加锁过程中执行的语句。

Page 127: 第 1 章   C# 入门基础

C#从入门到实践

6.6.4 checked和 unchecked 语句

checked 语句和 unchecked 语句用于控制整型算术运算和转换的溢出检查上下文。 checked 语句和 unchecked 语句完全等效于 checked 运算符和 unchecked 运算符(第 5.3 节)。不同的是, checked 语句和 unchecked 语句用于块,而不是表达式。

Page 128: 第 1 章   C# 入门基础

C#从入门到实践

6.7 实例一:判断闰年

【实例 6-1】演示了使用 if 语句判断指定的年份是否为闰年。该功能由 IsLeapYear(int year)静态函数( year参数类型为 int ,表示年份)实现。其中,判断指定的年份是否为闰年的规则如下。

能被 4 整除而不能被 100 整除的年份,则是闰年。 能被 400 整除的年份,则是闰年。不满足上述任何一个条件的年份,则不是闰年。

Page 129: 第 1 章   C# 入门基础

C#从入门到实践

6.8 小结

本章主要介绍了 C# 语言中的语句,如基本语句、跳转语句、选择语句、迭代语句、其他语句等。其中,读者要着重掌握基本语句、跳转语句、选择语句和迭代语句,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的命名空间。

Page 130: 第 1 章   C# 入门基础

C#从入门到实践

6.9 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_06” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ IFStatement” 的方法,且在该方法中使用 if 语句。( 3 )创建一个名称为“ SwitchStatement” 的方法,且在该方法中使用

switch 语句。( 4 )创建一个名称为“ ForStatement” 的方法,且在该方法中使用 for 语句

。( 5 )创建一个名称为“ ForeachStatement” 的方法,且在该方法中使用

foreach 语句。( 6 )创建一个名称为“ WhileStatement” 的方法,且在该方法中使用 while

语句。( 7 )创建一个名称为“ DoStatement” 的方法,且在该方法中使用 do 语句

。( 8 )创建一个名称为“ TryStatement” 的方法,且在该方法中使用 try 语句

Page 131: 第 1 章   C# 入门基础

C#从入门到实践

第 7 章 命名空间

C# 语言的程序是利用命名空间( namespace )组织起来的,它为 C# 语言的类型系统提供唯一的完全限定名称。命名空间既用作程序的“内部”组织系统,也用作“外部”组织系统(相对于其他程序而言的,一种用来公开程序本身所拥有元素的方法)。本章将讲解 C# 语言的命名空间,主要介绍以下知识点。

声明命名空间; . (点号)运算符; :: (双冒号)运算符; using指令; .NET Framework 常用命名空间。

Page 132: 第 1 章   C# 入门基础

C#从入门到实践

7.1 命名空间概述

命名空间( namespace )是一种用于组织 C# 程序代码中的不同类型的方式,并使类型具有唯一的完全限定名称。在概念上,命名空间和计算机文件系统中的文件夹比较类似。命名空间具有以下 4 个用途。

组织大型代码项目。 使用 . 运算符将它们分隔。 using指令不必为每个类指定命名空间的名称。 global命名空间是 .NET Framework 应用程序的“根”命名空间, global::System始终引用 .NET Framework 中的System命名空间。

Page 133: 第 1 章   C# 入门基础

C#从入门到实践

7.2 声明命名空间

namespace 关键字用于声明一个范围,并称该范围为命名空间。通过命名空间可以组织程序的源代码,并为源代码提供一个全局唯一类型访问的方法。声明命名空间的具体语法如下。

namespace qualified-identifier

{

body

[;]

}

qualified-identifier 表示命名空间的名称,该名称必须唯一, body表示该命名空间的内容主体(该部分是不可缺少的), ; (分号)是一个可选项。一旦声明了一个命名空间之后,该命名空间中的主体源代码将在该命名空间中进行编译。

Page 134: 第 1 章   C# 入门基础

C#从入门到实践

7.3 . (点号)运算符

. (点号)运算符用于成员访问。在命名空间中, . (点号)运算符指定命名空间的成员。【示例 7-7】使用 . (点号)运算符访问了 System命名空间下的 Int32 类型,并声明了该类型的 i变量。

System.Int32 i;

Page 135: 第 1 章   C# 入门基础

C#从入门到实践

7.4 :: (双冒号)运算符

:: (双冒号)运算符用于在指定命名空间中查找标识符,它通常放置在两个标识符之间。【示例 7-10】使用 :: (双冒号)运算符在 global命名空间中查找 System.Console类,并调用 WriteLine() 方法在控制台上显示“ This is a string.”字符串。

global::System.Console.WriteLine("This is a string.");

注意: global 表示在全局命名空间中的查找,而不是在个别特定的命名空间中查找。

Page 136: 第 1 章   C# 入门基础

C#从入门到实践

7.5 using指令

using 关键字存在两种常用用法:作为指令和作为语句。当using 关键字作为指令时,它用于为命名空间或类型创建别名或导入其他命名空间中定义的类型。当 using 关键字作为语句时,它用于定义一个范围,并在此范围的末尾将释放对象。本节介绍 using 关键字作为指令的详细用法。

Page 137: 第 1 章   C# 入门基础

C#从入门到实践

7.5.1 创建命名空间或类型别名

using指令可以为一个命名空间或类型创建特定的、简单的别名,使得通过该别名也可以引用该命名空间或类型。具体语法如下:

using old-identifier = new- identifier;

old-identifier 表示命名空间或类型的旧名称, new- identifier 表示该命名空间或类型的新名称,即别名。

Page 138: 第 1 章   C# 入门基础

C#从入门到实践

7.5.2 导入命名空间

using指令还可以将一个命名空间中所包含的类型导入到指定的程序体或文件中,从而该程序体或文件中的代码可以直接访问该命名空间中的类型,而不需要加上类型的完全限定符(如命名空间的名称)。具体语法如下:

using identifier;

identifier 表示被导入的命名空间。

Page 139: 第 1 章   C# 入门基础

C#从入门到实践

7.6 .NET Framework 常用命名空间

Microsoft .NET Framework 类库( Class Library )是一个综合性的面向对象的可重用类型集合,由 .NET Framework SDK 中的类、接口、值类型等组成的库。 .NET Framework 类库是创建 .NET Framework 应用程序、组件和控件的基础,并为开发人员提供了大量的命名空间、类等基础技术。

Page 140: 第 1 章   C# 入门基础

C#从入门到实践

7.7 小结

本章主要介绍了 C# 语言中的命名空间,如声明命名空间、 .(点号)运算符、 :: (双冒号)运算符、 using指令、 .NET Framework 常用命名空间等。其中,读者要着重掌握声明命名空间、 using指令和 .NET Framework常用命名空间,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的类。

Page 141: 第 1 章   C# 入门基础

C#从入门到实践

7.8 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_07” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )设置 class1.cs文件的命名空间为“ MyTest_07_01”

。( 3 )将名称为“ class2.cs” 的文件添加到该应用程序中。( 4 )设置 class2.cs文件的命名空间为“ MyTest_07_02”

Page 142: 第 1 章   C# 入门基础

C#从入门到实践

第 8 章 类

C# 是面向对象的编程语言,它使用类和结构来实现类型(如Windows 窗体、 ASP.NET Web 窗体、用户界面控件等)。典型的 C# 应用程序由程序员定义的类和 .NET Framework 的类组成。本章将讲解 C# 语言中的类,主要介绍以下知识点。

类概述; 类数据成员; 类函数成员 创建派生类;展示类的多态性。

Page 143: 第 1 章   C# 入门基础

C#从入门到实践

8.1 类概述

类( class )是一种数据结构,它可以包含数据成员(常量和字段)、函数成员(方法、属性、事件、索引器、运算符、实例构造函数、静态构造函数和析构函数)以及嵌套类型。类类型支持继承,继承是一种机制,它使派生类可以对基类进行扩展和专用化。

Page 144: 第 1 章   C# 入门基础

C#从入门到实践

8.1.1 类声明

声明类需要使用 class 关键字,语法如下。class-modifiers class identifier class-base class-body ;

class-modifiers 表示类修饰符(可选), identifier 表示类的名称, class-base 表示类的基类或接口等(可选), class-body 表示类体, ; (分号)是可选的。

Page 145: 第 1 章   C# 入门基础

C#从入门到实践

8.1.2 类修饰符

类修饰符放在 class 关键字的前面,它包括new、 public、 protected、 internal、 private、 abstract和 sealed共 7 个关键字。其中, public、 protected、 internal和 private修饰符控制类的可访问性。它们的意义具体说明如下。

public修饰符表示该类是公开的,访问不受限制。 protected修饰符表示该类只能是本身或其派生的类访问。 internal修饰符表示该类只能是在当前应用程序中访问。 private修饰符表示该类只能是本身访问。

Page 146: 第 1 章   C# 入门基础

C#从入门到实践

8.1.3 类继承

类类型支持继承( inherit ),继承是一种机制,它使派生类可以对基类进行扩展和专用化。在类声明语法中, class-base 表示类的基类或接口等(可选),即一个类可以从另外一个类继承而来。

Page 147: 第 1 章   C# 入门基础

C#从入门到实践

8.1.4 类、对象和实例化

类是一种数据结构,它为动态创建类的实例提供了定义。类的实例又称为对象。实例化是一种操作,它可以为类的实例分配内存。

Page 148: 第 1 章   C# 入门基础

C#从入门到实践

8.2 类成员

类可以包含多种成员,如常量、字段、方法等,具体说明如下。( 1 )常量 ( 2 )字段( 3 )方法 ( 4 )属性( 5 )事件 ( 6 )索引器( 7 )运算符 ( 8 )实例构造函数( 9 )析构函数 ( 10 )静态构造函数( 11 )类型上述成员除了类型之外,可以分类两大类:数据成员和函数成员

。其中,数据成员包括常量和字段;函数成员包括方法、属性、事件、索引器、运算符、实例构造函数、析构函数和该类的静态构造函数。本节将详细介绍上述类的成员。

Page 149: 第 1 章   C# 入门基础

C#从入门到实践

8.2.1 常量

常量( constant )用来表示常数值,它的值在编译时计算。常量的类型必须为 sbyte、 byte、 short、 ushort、 int、 uint、 long、 ulong、 char、 float、 double、 decimal、 bool、 string 、枚举类型或引用类型。

在声明常量时,需要使用 const 关键字。

Page 150: 第 1 章   C# 入门基础

C#从入门到实践

8.2.2 字段

字段( field )是类中最为常见的数据成员,它为类中的变量。如果在同一个语句中同时声明多个字段,那么字段之间需要使用 , (逗号)分隔。根据字段的修饰方式,可以把字段分为以下 4 种。

静态字段,使用 static修饰,对应于静态变量。 实例字段,不使用 static修饰,对应于实例变量。只读字段,使用 readonly修饰。 易失字段,使用 volatile修饰。该类型的字段很少使用,

在此不做详细介绍。

Page 151: 第 1 章   C# 入门基础

C#从入门到实践

8.2.3 方法

方法( method )是包含一系列语句的代码块,通过这些代码块能够实现预先定义的计算或操作。方法一般声明在类或结构中,由访问级别、返回值、方法名称、方法参数和方法体组成。其中,访问级别、返回值、方法名称和方法参数统称为方法的“签名”。方法参数包括在小括弧(“()”)中,多个参数使用 , (逗号)分隔。如果为空括号,则表示该方法不需要参数。

1 .方法参数2 .静态方法和实例方法3 .虚方法和重写方法4 .密封方法5 .抽象方法

Page 152: 第 1 章   C# 入门基础

C#从入门到实践

8.2.4 属性

属性( property )是 C# 语言所特有的一种机制,它可以用于访问对象或类的特性的成员。属性和字段非常相似,而且访问属性和字段的语法相同。但是,属性不表示存储位置(字段表示一个存储位置)。

属性通过一种被称为访问器的机制来获取或修改其值。其中,获取属性的值的访问器为称为 get 访问器,修改属性的值的访问器被称为 set 访问器,它们的具体说明如下:

get 访问器相当于一个无参数方法,且该访问的返回值的类型和属性的类型相同。在 get 访问器中,必须包含return 语句,返回该属性的值。

set 访问器相当于一个返回类型为 void 的方法,且该方法只有一个参数,参数的类型和属性的类型相同。特别地,该方法的参数名称始终约定为 value 。

Page 153: 第 1 章   C# 入门基础

C#从入门到实践

8.2.5 索引器

索引器( indexer )其实是一种含有参数的属性,又称为含参属性。它提供索引的方式来访问对象,即与数组的访问方式相同。声明索引器时,需要使用 this 关键字。

Page 154: 第 1 章   C# 入门基础

C#从入门到实践

8.2.6 构造函数

构造函数是类的一种特定的方法,它的名称和其所属类的名称相同。构造函数是在创建给定类型的对象时执行的类方法,通常用来初始化新对象的数据成员,即设置数据成员的默认值。在任何时候,只要创建类,就会调用它的构造函数。如果开发人员没有为类显式提供构造函数,则默认情鱿 C# 编译器将为该类创建一个默认的构造函数

1 .实例构造函数2 .静态构造函数

Page 155: 第 1 章   C# 入门基础

C#从入门到实践

8.2.7 析构函数

析构函数( destructor )是一种用于实现销毁类实例所需操作的成员。它和类的构造函数恰恰相反,类的构造函数用来初始化该类的实例,而析构函数用来释放该类的实例占用的资源,并销毁该类的实例。

析构函数的名称和类的名称一样,并带有“ ~”字符。

Page 156: 第 1 章   C# 入门基础

C#从入门到实践

8.2.8 事件

事件( event )是一种使对象或类能够提供通知的成员。客户端可以通过提供事件处理程序( event handler )为相应的事件添加可执行代码。类或对象可以通过事件向其他类或对象通知发生的相关事情。

一个类或对象可以事先向其他类或对象注册一个事件,然后在一定的时候引发该事件。如开发人员可以向在Windows 窗体中的按钮注册一个事件,当用户单击该按钮时,将引发该已注册的事件。有关事件的知识点将在第12 章中详细介绍。

Page 157: 第 1 章   C# 入门基础

C#从入门到实践

8.3 实例一:使用类的继承特性

本实例创建了 3 个类: Person、 Teacher和Student。 Teacher和 Student 类都继承与 Person 类,它们的继承关系如图 8.1所示。

Page 158: 第 1 章   C# 入门基础

C#从入门到实践

8.3.1 设计 Person 类

Person 类包含 3 个字段: name、 age和 courses 。其中, name字段表示姓名,类型为 string; age字段表示年龄,类型为 int; courses字段表示课程列表,它为一个元素类型为 string 的数组。

Page 159: 第 1 章   C# 入门基础

C#从入门到实践

8.3.2 设计 Teacher 类

Teacher 类继承于 Person 类,且还包含 1 个字段: duty 。该字段表示职务,类型为 string 。

Page 160: 第 1 章   C# 入门基础

C#从入门到实践

8.3.3 设计 Student 类

Student 类继承于 Person 类,且还包含 1 个字段:className 。该字段表示班级,类型为 string 。

Page 161: 第 1 章   C# 入门基础

C#从入门到实践

8.3.4 测试 Person、 Teacher和Student 类

【实例 8-1】测试 Person、 Teacher和 Student 类,并介绍了类的使用方法。

Page 162: 第 1 章   C# 入门基础

C#从入门到实践

8.4 小结

本章主要介绍了 C# 语言中的类,如类概述、类数据成员、类函数成员、派生类、多态性等。其中,读者要着重掌握类的数据成员和函数成员,以及使用类的派生和多态性来创建派生类的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的结构。

Page 163: 第 1 章   C# 入门基础

C#从入门到实践

8.5 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_08” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ MyClass” 的类,并在该类中定义

如下成员。 sum 常量; value字段; GetValue() 方法; Index属性; 只包含一个类型为 int 的参数、且返回类型为 string 的索引器

; printHandler事件。

Page 164: 第 1 章   C# 入门基础

C#从入门到实践

第 9 章 结构

结构和类非常相似。和类相比,结构更加适合用于表示轻量级对象(如复数、坐标、矩阵、颜色等)。通过结构,只要使用少量数据成员,就能够表示这些轻量级对象,从而简化了应用程序。本章将讲解 C# 语言中的结构,主要介绍以下知识点。

结构概述; 结构成员; 结构和类的区别 创建 Point 结构; 创建 Complex 结构。

Page 165: 第 1 章   C# 入门基础

C#从入门到实践

9.1 结构概述

结构( struct )与类非常相似,它们都表示可以包含数据成员(常量和字段)和函数成员(方法、属性、事件、索引器、运算符、实例构造函数和静态构造函数)的数据结构。但是,结构是一种值类型,结构类型的变量直接包含了该结构的数据。类类型是一种引用类型,类类型的变量仅仅包含访问某个数据的一个引用(或地罚

1 .结构声明2 .结构修饰符

Page 166: 第 1 章   C# 入门基础

C#从入门到实践

9.2 结构成员

结构和类一样,它也包含多种成员,如常量、字段、方法等,具体说明如下。

常量 字段 方法 属性 事件 索引器 运算符 实例构造函数 静态构造函数 类型上述成员除了类型之外,可以分类两大类:数据成员和函数成员。其中,数据成员包括常量和字段;函数成员包括方法、属性、事件、索引器、运算符、实例构造函数和静态构造函数。

Page 167: 第 1 章   C# 入门基础

C#从入门到实践

9.3 结构和类的区别

结构和类虽然比较相似,但是还存在以下 8 个方面的区别。结构是值类型,并隐式地从类 System.ValueType继承,而类是引用类型,并从类

object继承。结构总是分配在堆栈上,而类常常分配在堆上。如果对结构类型的变量进行赋值,那么将创建所赋的值的一个副本。

结构类型字段的默认值是字段本身的类型的默认值,而类类型字段的默认值为 null。因此,结构是存在默认值的。

结构不能声明无参数的实例构造函数。结构不能声明析构函数。在结构中,初始化实例字段是错误的。对于结构而言,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且

不能作为一个类的基。但是,结构从基类 Object继承。结构可实现接口,其方式同类完全一样。

实例化结构时,可以不使用 new 运算符,而且结构对象的字段具有默认初始值。而实例化类时,必须使用 new 运算符,并需要设置各个字段的初始值。

Page 168: 第 1 章   C# 入门基础

C#从入门到实践

9.3.1 继承

结构不支持继承。因此,在声明结构成员时,不能使用protected或 protected internal修饰符。结构类型永远不会是抽象的,并且始终是隐式密封的。因此,结构不能作为其他结构或类的基结构,而且在声明结构时,不能使用abstract或 sealed修饰符。

Page 169: 第 1 章   C# 入门基础

C#从入门到实践

9.3.2 this保留字

this 是一个保留字,它只能在实例构造函数、实例方法或实例访问器的块中使用,且表示当前实例。在类中, this 表示当前实例,它的值不能被修改。在结构中, this相当于一个变量。如果在结构的实例构造函数中, this相当于一个结构类型的 out参数;如果在结构的实例函数成员中, this相当于一个结构类型的 ref参数。

Page 170: 第 1 章   C# 入门基础

C#从入门到实践

9.3.3 构造函数

在结构中,不能声明无参数的实例构造函数。其实,每一个结构都隐式地具有一个无参数实例构造函数,该构造函数将初始化该结构所有字段的值。如果字段的类型为值类型,则将该字段的值设置为其类型的默认值。如果字段的类型为引用类型,则将该字段的值设置为 null 。

另外,结构还可以声明带有参数的实例构造函数。

Page 171: 第 1 章   C# 入门基础

C#从入门到实践

9.4 实例一:创建坐标点结构 Point

本实例创建一个名称为 Point 的结构,用来表示二维坐标值。该结构包含 2 个属性: X和 Y ,它们分别表示 X坐标值和 Y坐标值。

Page 172: 第 1 章   C# 入门基础

C#从入门到实践

9.4.1 设计 Point 结构

Point 结构包含 2 个字段: x和 y 。其中, x字段表示 X坐标的值, y字段表示 Y坐标的值,它们的类型都为 int 。

Page 173: 第 1 章   C# 入门基础

C#从入门到实践

9.4.2 测试 Point 结构

【实例 9-1】测试了 Point 结构,并使用该结构创建一个实例 p ,然后显示该实例的 X坐标和 Y坐标的值。

Page 174: 第 1 章   C# 入门基础

C#从入门到实践

9.5 实例二:创建复数结构 Complex

本实例创建一个名称为 Complex 的结构,用来表示一个复数。该结构包含 2 个属性: Integer和 Fraction ,它们分别表示复数的整数部分和小数部分。另外,该结构重载了 +运算符,并使用该运算符计算了两个复数的和。

Page 175: 第 1 章   C# 入门基础

C#从入门到实践

9.5.1 设计 Complex 结构

Complex 结构包含 2 个字段: integer和 fraction 。其中, integer字段表示复数的整数部分, fraction字段表示复数的小数部分,它们的类型都为 int 。

Page 176: 第 1 章   C# 入门基础

C#从入门到实践

9.5.2 测试 Complex 结构

【实例 9-2】测试了 Complex 结构,并使用该结构创建两个实例 lc和 rc ,然后计算这两个实例的和,并显示计算结果。

Page 177: 第 1 章   C# 入门基础

C#从入门到实践

9.6 小结

本章主要介绍了 C# 语言中的结构,如结构概述、结构成员、结构和类的区别、 Point 结构、 Complex 结构等。其中,读者要着重掌握结构的成员,以及创建结构的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的数组。

Page 178: 第 1 章   C# 入门基础

C#从入门到实践

9.7 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_09” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ MyStruct” 的类,并在该类中定义

如下成员。 sum 常量; value字段; GetValue() 方法; Index属性;只包含一个类型为 int 的参数、且返回类型为 string 的索引器;

printHandler事件。

Page 179: 第 1 章   C# 入门基础

C#从入门到实践

第 10 章 数组

数组可以将多个类型相同的元素组合为一个整体,从而通过数组统一访问或操作这些元素。数组是 C# 语言最常用的数据结构之一。它是相同数据类型的对象的集合。该集合的长度(即数组的长度)可以为 0 或大于 0 的整数。本章将讲解使用数组进行编程的方法,主要介绍以下知识点。

数组概述;数组分类;静态数组;动态数组;抽签程序。

Page 180: 第 1 章   C# 入门基础

C#从入门到实践

10.1 数组概述

数组是一个有序的数据集合。数组中的每一个元素的数据类型都相同。元素的数据类型被称为元素类型,它可以为任何类型,甚至可以为数组。数组可以用一个统一的数组名和下标来唯一确定组中的元素。例如,一个班有 50名学生,可以用 s1、 s2、 s3、…、 s50 表示 50 个学生的成绩。 s 为数组名,下标表示学生的序号。 s10 (整数 10 为下标)表示第 10 个学生的成绩。

Page 181: 第 1 章   C# 入门基础

C#从入门到实践

10.1.1 数组的维度数

大家都知道,直线由点构成,平面由直线构成、空间由平面构成。如果要描述直线上的一个点,则只需要一个值。如果要描述平面上的一个点,则需要两个值。如果要描述空间中的一个点,则需要 3 个值。在直线、平面和空间中,称描述一个点所需要值的数量为“维度数”。

数组也一样,它也存在维度数的概念。当在要描述数组中的一个元素时,如果只需要一个值(数组的下标),那么该数组的维度数为 1 ;如果需要两个值,那么该数组的维度数为 2 ;依次类推。如上述提及的 s数组的维度数就是 1。根据数组的维度数不同,可以把数组分为以下 3 种类型

一维数组,维度数为 1 的数组。二维数组,维度数为 2 的数组。 多维数组,维度数大于 2 的数组。

Page 182: 第 1 章   C# 入门基础

C#从入门到实践

10.1.2 声明数组

在 C# 程序设计中,如果需要某一个数组,则必须首先声明该数组。声明一维数组的语法如下所示。

type[] arrayName;

其中, type 表示数组元素的类型,如 int、 double、 string、 object 等; arrayName 表示数组的名称。

Page 183: 第 1 章   C# 入门基础

C#从入门到实践

10.1.3 实例化数组

实例化数组就是为数组分配相应的内存。注意,声明一个数组,并不为该数组分配相应的内存。

Page 184: 第 1 章   C# 入门基础

C#从入门到实践

10.1.4 初始化数组

初始化数组就是初始化数组中每一个元素的值,即为数组中的每一个元素进行赋值。数组被实例化之后,每个元素都为其元素类型的默认值。一般情况下,只有初始化数组之后,该数组才具有实际运算的意义。初始化数组存有多种方法,主要包括以下 4 种。

1 .直接赋值2 .使用“ new” 操作符,并指定了数组的长度3 .使用“ new” 操作符,省略数组的长度4 .直接设置数组的每一个元素的值

Page 185: 第 1 章   C# 入门基础

C#从入门到实践

10.1.5 遍历数组

遍历数组是指依次访问数组中的每一个元素,并执行预先设计的操作。访问数组的元素最常用方法之一就是使用下标(或索引)。根据是否使用下标可以遍历数组方式分为两种。第一种,使用下标遍历,如 for、 while、 do…while 等语句。第二种,不使用下标遍历,如 foreach 语句。

1 .使用下标遍历数组2 .不使用下标遍历数组

Page 186: 第 1 章   C# 入门基础

C#从入门到实践

10.2 数组分类

根据数组的维度数和元素的类型不同,可以把数组分为 4 种类型:一维数组(维度数为 1 的数组)、二维数组(维度数为 2 的数组)、多维数组(维度数大于 2 的数组)和交错数组(元素的类型为数组的数组)。本小节将介绍声明、实例化和初始化各种不同类型数组的方法。

Page 187: 第 1 章   C# 入门基础

C#从入门到实践

10.2.1 一维数组

一维数组是指维度数为 1 的数组,它是最简单的数组,也是最常用的数组。声明一维数组的语法如下所示。

type[] arrayName;

其中, type 表示数组元素的类型,如 int、 double、 string、 object 等; arrayName 表示数组的名称。

Page 188: 第 1 章   C# 入门基础

C#从入门到实践

10.2.2 二维数组

二维数组是指维度数为 2 的数组。声明二维数组的语法如下所示。

type[,] arrayName;

其中, type 表示数组元素的类型,如 int、 double、 string、 object 等;中括号( [] )中间存在一个逗号( , )表示该数组为一个二维数组; arrayName 表示数组的名称。

Page 189: 第 1 章   C# 入门基础

C#从入门到实践

10.2.3 多维数组

多维数组是指维度数大于 2 的数组,如三维数组、四维数组等。声明三维数组的语法如下所示。

type[, ,] arrayName;

其中, type 表示数组元素的类型,如 int、 double、 string、 object 等;中括号( [] )中间存在两个逗号( , )表示该数组为一个三维数组; arrayName 表示数组的名称。

Page 190: 第 1 章   C# 入门基础

C#从入门到实践

10.2.4 交错数组

交错数组又称为“数组的数组”,它的元素也为一个数组。声明二维交错数组的语法如下所示。

type[][] arrayName;

其中, type 表示数组元素的类型,如 int、 double、 string、 object 等; type 关键字之后包含两个中括号( [] )表示该数组为一个二维交错数组; arrayName 表示数组的名称。

Page 191: 第 1 章   C# 入门基础

C#从入门到实践

10.3 静态数组 System.Array

.NET 框架提供了两种数组:静态数组和动态数组。一旦为数组分配内存之后,如果该数组的大小是不能修改的,则称该数组为静态数组;反之,则称之为动态数组。静态数组静态数组由 System.Array 类实现,动态数组由System.ArrayList 类实现。本小节将介绍静态数组的基本属性和方法,以及它们的使用方法。

注意:本章前面小节所介绍的数组都是属于静态数组。

Page 192: 第 1 章   C# 入门基础

C#从入门到实践

10.3.1 属性

System.Array 类包含 7 个属性,如获取数组长度的 Length属性、获取数组秩的 Rank 等,如表 10.1所示。

属性 描述Length 数组的长度,即数组所有维度中元素的总数。

该值为 32位整数。LongLength 数组的长度,即数组所有维度中元素的总数。

该值为 64位整数。Rank 数组的秩,即数组的维度数。IsFixedSize 表示数组的大小是否固定。IsReadOnly 表示数组是否为只读。IsSynchronized 表示是否同步访问数组。SyncRoot 获取同步访问数组的对象。

Page 193: 第 1 章   C# 入门基础

C#从入门到实践

10.3.2 方法System.Array 类包含多个方法,如获取数组长度的 GetLength() 方法、获取指定元素值的 GetValue() 方法,获取指定元素索引的IndexOf() 方法等,如表 10.2所示。属性 描述

GetValue() 获取指定元素的值。

SetValue() 设置指定元素的值。

Clear() 清空数组中的所有元素。

GetLength() 获取指定维的元素数量。该值为 32位整数。

GetLongLength() 获取指定维的元素数量。该值为 64位整数。

IndexOf() 获取匹配的第一个元素的索引。

LastIndexOf() 获取匹配的最后一个元素的索引。

FindIndex() 搜索指定元素,并获取第一个匹配元素的索引。

FindLastIndex() 搜索指定元素,并获取最后一个匹配元素的索引。

Copy() 将一个数组中的一部分元素复制到另一个数组。

CopyTo() 将一维数组的所有元素复制到另外一个一维数组。

Clone() 复制数组。

ConstrainedCopy() 指定开始位置,并复制一系列元素到另外一个数组中。

Sort() 对一维数组中的元素进行排序。

Reverse() 反转一维数组中元素的顺序。

BinarySearch() 使用二进制搜索算法在一维的排序数组中搜索指定元素。

GetLowerBound() 获取数组中指定维度的下限。

GetUpperBound() 获取数组中指定维度的上限。

Page 194: 第 1 章   C# 入门基础

C#从入门到实践

10.3.3 获取数组长度

数组长度是指数组元素的总数,即数组每一维度元素数量之乘积。获取数组长度的方法存在多种,可以通过System.Array 类的属性获取,也可以通过 Array 类的方法获取。

1 .通过属性获取数组的长度2 .通过方法获取数组的长度

Page 195: 第 1 章   C# 入门基础

C#从入门到实践

10.3.4 获取元素的值

获取数组中指定元素的值最简单方法就是通过“ []” 运算符。

Page 196: 第 1 章   C# 入门基础

C#从入门到实践

10.3.5 设置元素的值

和获取指定元素的值一样,也存在两种方法设置元素的值。第一种方法就是直接通过数组名和“ []” 运算符来设置元素的值。

Page 197: 第 1 章   C# 入门基础

C#从入门到实践

10.3.6 获取元素的索引

System.Array 类为一维数组提供了获取元素的索引的两个静态方法: IndexOf()和 LastIndexOf() 方法。 IndexOf() 方法获取匹配的、第一个元素的索引。 LastIndexOf() 方法获取匹配的、最后一个元素的索引。

Page 198: 第 1 章   C# 入门基础

C#从入门到实践

10.3.7 排序数组

System.Array 类为一维数组提供了一个名称为“ Sort()” 的方法,该方法可以对一维数组中的元素进行排序。能够使用 Sort() 方法排序的数组中的元素必须实现 IComparable接口,即数组中的元素是能够进行比较的,否则不能对该数组中的元素进行排序。

Page 199: 第 1 章   C# 入门基础

C#从入门到实践

10.3.8 反转数组

System.Array 类为一维数组提供了一个名称为“ Reverse()”的方法,该方法可以反转一维数组中的全部元素或部分连续的元素。

Page 200: 第 1 章   C# 入门基础

C#从入门到实践

10.4 动态数组 System.ArrayList

动态数组又称为可变数组,且数组的长度可以动态修改。动态数组由 System.ArrayList 类实现,它在保存元素时,仅仅保存元素的引用,而不是元素的具体值。因此,动态数组元素的数据类型可以是任何类型,而且各个元素的数据类型也可以不相同。

Page 201: 第 1 章   C# 入门基础

C#从入门到实践

10.4.1 属性

System.ArrayList 类包含了 7 个属性,如获取数组元素数量的Count属性、指示数组是否为只读的 ReadOnly属性等,如表 10.3所示。属性 描述Capacity 数组的容量。Count 数组元素的数量。Item 指定索引处的元素。IsFixedSize 表示数组的大小是否固定。

IsReadOnly 表示数组是否为只读。

IsSynchronized 表示是否同步访问数组。SyncRoot 获取同步访问数组的对象。

Page 202: 第 1 章   C# 入门基础

C#从入门到实践

10.4.2 方法

System.ArrayList 类包含了多个方法,如添加新元素到数组末尾中的 Add() 方法、从数组中删除指定元素的Remove() 方法等。

Page 203: 第 1 章   C# 入门基础

C#从入门到实践

10.4.3 添加元素

向动态数组添加一个新的元素可以使用 Add() 方法或者Insert() 方法。 Add() 方法可以将新的元素添加到数组的末尾处, Insert() 方法可以将新的元素添加到数组的指定位置。如果希望把新的元素插入到数组(元素数量大于 0)的开始处,则只能使用 Insert() 方法。

Page 204: 第 1 章   C# 入门基础

C#从入门到实践

10.4.4 移除元素

如果要从动态数组中移除元素,则可以使用Remove()、 RemoveAt()或 RemoveRange() 方法。 Remove() 方法从数组中移除指定的元素, RemoveAt() 方法从数组中移除指定位置处的元素, RemoveRange() 方法从数组中移除指定范围内的元素。

Page 205: 第 1 章   C# 入门基础

C#从入门到实践

10.5 实例一:抽签程序

【实例 10-1】使用整型数组实现抽签功能。该功能由Draw(int count)函数实现, count参数表示签号的总数量。

Page 206: 第 1 章   C# 入门基础

C#从入门到实践

10.6 小结

本章主要介绍了 C# 语言中的数组,如数组概述、数组分类、静态数组、动态数组、抽签程序等。其中,读者要着重掌握数组分类、一维数组、静态数组和动态数组,以及使用数组编程的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的接口。

Page 207: 第 1 章   C# 入门基础

C#从入门到实践

10.7 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_10” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ UsingArray” 的类,并在该类中定义

如下成员,并使用这些成员测试 Array 类的各个方法的用途。

名称为“ values1” 的、元素类型为 int 的一维数组;名称为“ values2” 的、元素类型为 string 的一维数组;名称为“ values3” 的、元素类型为 int 的二维数组;名称为“ values4” 的、元素类型为 string 的一维数组;名称为“ values5” 的、元素类型为 int 的三维数组;名称为“ values6” 的、元素类型为 int 的交错数组。

Page 208: 第 1 章   C# 入门基础

C#从入门到实践

第 11 章 接口

接口和类一样,也是属于引用类型。接口可以用来描述属于类或结构的一组相关功能,即定义一种协议。类或结构可以实现接口,同时必须遵循它们所实现接口定义的协议。本章将讲解 C# 语言中的接口,主要介绍以下知识点。

接口概述; 接口成员; 实现接口;抽象类和接口。

Page 209: 第 1 章   C# 入门基础

C#从入门到实践

11.1 接口概述

接口( interface )定义一种协议,实现该接口的类或结构必须遵循该协议。一个接口可以继承于一个或多个其他接口,一个类或结构也可以实现一个或多个接口。接口可以包含 4 种成员:方法、属性、事件和索引器。接口本身不提供它所定义的成员的实现,它仅仅指定实现该接口的类或结构必须提供的成员。

Page 210: 第 1 章   C# 入门基础

C#从入门到实践

11.1.1 接口声明

声明接口需要使用 interface 关键字,语法如下。interface-modifiers interface identifier interface-base

interface-body ;

interface-modifiers 表示接口修饰符(可选), identifier 表示接口的名称, interface-base 表示接口的基接口(可选), interface-body 表示接口体, ; (分号)是可选的。 4

Page 211: 第 1 章   C# 入门基础

C#从入门到实践

11.1.2 接口修饰符

接口修饰符一般位于接口声明中的 interface 关键字之前,共包括 5 个修饰符: new、 public、 protected、 internal和 private 。其中, public、 protected、 internal和private修饰符控制接口的可访问性。它们的意义具体说明如下。

public修饰符,表示该接口是公开的,访问不受限制。 protected修饰符,表示该接口只能是本身或其派生的接口访问。

internal修饰符,表示该接口只能是在当前应用程序中访问。

private修饰符,表示该接口只能是本身访问。

Page 212: 第 1 章   C# 入门基础

C#从入门到实践

11.1.3 接口继承

接口可以继承于一个或多个其他接口,也可以不继承。被继承的接口称为该接口的显式基接口。当一个接口具有一个或多个显式基接口时,在声明该接口时,接口标识符后就要紧跟一个冒号和一个由 , (逗号)分隔的基接口标识符列表。

Page 213: 第 1 章   C# 入门基础

C#从入门到实践

11.2 接口成员

接口的成员必须是方法、属性、事件或索引器,而不能包括常量、字段、运算符、实例构造函数、析构函数或类型,也不能包含任何种类的静态成员。一个接口可以不包括任何成员,也可以包括一个或多个成员。接口成员默认隐式地具有 public 访问属性,而且在声明接口成员时不能包含任何修饰符(如abstract、 public、 protected、 internal、 private、 virtual、 override和 static ),否则会发生编译时错误。

注意:一个接口的成员包括两部分:由接口本身声明的成员和其从基接口继承的成员。

Page 214: 第 1 章   C# 入门基础

C#从入门到实践

11.2.1 属性

在接口中声明属性时,只能声明该属性具有哪个访问器(如get或 set 访问器),而不能实现该访问器。接口属性的访问器只用于表明该属性是只读的、只写的还是读写的,访问器体必须始终是一个 ; (分号)。

Page 215: 第 1 章   C# 入门基础

C#从入门到实践

11.2.2 索引器

接口索引器和接口属性比较相似。在接口中声明索引器时,只能声明该索引器具有哪个访问器(如 get或 set 访问器),而不能实现该访问器。接口索引器的访问器只用于表明该索引器是只读的、只写的还是读写的,访问器体必须始终是一个 ; (分号)。

Page 216: 第 1 章   C# 入门基础

C#从入门到实践

11.2.3 方法

在接口中声明方法时,只能声明该方法的签名,而且该方法的方法体只能为 ; (分号),而不能包括该方法的实现代码。

Page 217: 第 1 章   C# 入门基础

C#从入门到实践

11.2.4 事件

在接口中声明事件时,只能声明该事件的签名,而且事件的名称之后必须接一个 ; (分号)。

Page 218: 第 1 章   C# 入门基础

C#从入门到实践

11.3 实现接口

类和结构都可以实现接口。如果某一个类或接口实现了一个或多个接口,那么在声明该类或结构时,将实现的接口的标识符包含在该类或结构的基类列表中。

Page 219: 第 1 章   C# 入门基础

C#从入门到实践

11.3.1 实现属性

实现接口属性即添加该接口属性的实现代码,接口属性的名称和实现该接口属性的名称相同。

Page 220: 第 1 章   C# 入门基础

C#从入门到实践

11.3.2 实现索引器

实现接口索引器即添加该接口索引器的实现代码。

Page 221: 第 1 章   C# 入门基础

C#从入门到实践

11.3.3 实现方法

实现接口方法即添加该接口方法的实现代码,接口方法的名称和实现该接口方法的签名相同。

Page 222: 第 1 章   C# 入门基础

C#从入门到实践

11.3.4 实现事件

实现接口事件即添加该接口事件的实现代码,接口事件的名称和实现该接口事件的签名相同。

Page 223: 第 1 章   C# 入门基础

C#从入门到实践

11.4 抽象类和接口

抽象类使用 abstract修饰符,它用于表示所修饰的类是不完整的,并且它只能用作基类。抽象类与非抽象类在以下 3个方面的区别。

抽象类不能直接实例化。如果抽象类使用 new 运算符,则发生编译时错误。

允许(但不要求)抽象类包含抽象成员。抽象类不能被密封。当从抽象类派生非抽象类时,这些非抽象类必须实现所继承

的所有抽象成员,即重写这些抽象成员。

Page 224: 第 1 章   C# 入门基础

C#从入门到实践

11.5 实例一:设计算术计算接口

【实例 11-1】设计了用于算术计算的 ICompute 接口。该接口包括 4 个方法,具体说明如下。

double Add(double leftValue,double rightValue) ,计算两个数的和。

double Sub(double leftValue,double rightValue) ,计算两个数的差。

double Multiply(double leftValue,double rightValue) ,计算两个数的积。

double Div(double leftValue,double rightValue) ,计算两个数的商。

Page 225: 第 1 章   C# 入门基础

C#从入门到实践

11.6 小结

本章主要介绍了 C# 语言中的接口,如接口概述、接口成员、实现接口,抽象类和接口区别等。其中,读者要着重掌握接口成员和实现接口的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的委托和事件。

Page 226: 第 1 章   C# 入门基础

C#从入门到实践

11.7 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_11” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ MyInterface” 的接口,并在该接口

中定义属性、索引器、方法、事件等成员。

Page 227: 第 1 章   C# 入门基础

C#从入门到实践

第 12 章 委托和事件

委托是 C# 语言中一种引用方法的类型,和 C++ 中处理函数指针的情况比较相似。不但可以向委托实例注册方法列表,而且还可以通过委托实例来调用方法列表中的方法。事件是一种特殊的委托,它包含两个参数:指示事件源的“对象源”参数和封装事件的其他任何相关信息的“ e”参数。本章将讲解 C# 语言中的委托和事件,主要介绍以下知识点。

声明委托; 委托实例化; 委托调用;声明事件; 注册事件和移除事件; 调用事件。

Page 228: 第 1 章   C# 入门基础

C#从入门到实践

12.1 委托

熟悉 C++ 中函数指针的读者可能比较容易理解委托。委托( delegate )是一种数据结构,它是用来处理类似于 C++中函数指针的情况,即委托能够引用静态方法或引用类实例及其实例方法。特别地,委托是完全面向对象的,同时也封装了对象实例和方法。

所有委托类型的基类是 System.Delegate类。 System.Delegate 类本身不是委托类型,而且不允许显式地直接从该来派生新的类型。委托实例封装了一个调用列表,该列表包含了一个或多个方法,每个方法称为一个可调用实体。

Page 229: 第 1 章   C# 入门基础

C#从入门到实践

12.1.1 委托声明

委托类型的声明将创建一个协定,该协定指定一个或多个方法的签名。委托是委托类型的实例,它可以引用静态方法或者实例方法。声明委托需要使用 delegate 关键字,语法如下。

delegate-modifiers delegate return-type identifier

delegate-modifiers 表示委托的修饰符(可选),它包括new、 public、 protected、 internal和 private共 5 个关键字。其中, public、 protected、 internal和 private修饰符控制委托的可访问性。它们的意义具体说明如下。

public修饰符,表示该委托是公开的,访问不受限制。 protected修饰符,表示该委托只能是本身委托访问。 internal修饰符,表示该委托只能是在当前应用程序中访问。 private修饰符,表示该委托只能是本身访问。

Page 230: 第 1 章   C# 入门基础

C#从入门到实践

12.1.2 创建向委托注册方法

一旦声明一个委托之后,那么就指定了该委托方法列表中的方法签名,包括方法列表中的方法的返回类型和方法参数。如果一个方法能够注册到某一个委托中,那个该方法的签名必须与该委托的所指定的签名完全匹配。匹配规则如下。

方法的返回类型必须和委托的返回类型相同。 方法的方法参数必须和委托的方法参数相同,参数的具体名称可以不相同。

Page 231: 第 1 章   C# 入门基础

C#从入门到实践

12.1.3 委托实例化

委托实例化可以创建委托类型的实例,并向该实例注册方法列表。委托类型的实例的方法列表可以为静态方法、实例方法或者另外一个委托实例。

注意:委托实例化,它把静态方法、实例方法或者另外一个委托的名称作为该实例的方法参数进行传递。

Page 232: 第 1 章   C# 入门基础

C#从入门到实践

12.1.4 委托的方法列表

一个委托实例都必须包含其方法列表,方法列表可以包含一个或多个方法。委托实例除了在其实例化时注册方法之外,还可以通过“ +” 或“ +=” 运算符向该实例的方法列表中的注册方法,通过“ -” 或“ -=” 运算符向该实例的方法列表中的移除方法

Page 233: 第 1 章   C# 入门基础

C#从入门到实践

12.1.5 委托调用

一个委托实例的方法列表,又称为该委托实例的调用列表。一个调用列表可能包含一个或多个方法。如果一个调用列表包含多个方法时,当该委托实例被调用时,它将按照调用列表中方法的注册顺序依次调用每一个方法。

Page 234: 第 1 章   C# 入门基础

C#从入门到实践

12.2 事件

事件( event )是一种使对象或类能够提供通知的成员。客户端可以通过提供事件处理程序为相应的事件添加可执行代码。客户端可以实现为事件定义一些操作或方法,当事件发生时,将调用该事件事先定义的操作或方法。

Page 235: 第 1 章   C# 入门基础

C#从入门到实践

12.2.1 声明事件

事件其实是一种特殊类型的委托,它包含两个参数:指示事件源的“对象源”参数和封装事件的其他任何相关信息的“ e”参数。其中,“ e”参数的类型为 System.EventArgs类型或从 System.EventArgs 类派生的类型。声明事件一般包括以下两个步骤。

( 1 )声明事件的委托。( 2 )声明事件本身。

Page 236: 第 1 章   C# 入门基础

C#从入门到实践

12.2.2 注册事件

一个事件一旦声明之后,该事件的默认值为 null 。如果希望该事件执行事先指定的操作,则首先向该事件注册方法列表(即委托的调用列表)。注册事件可以使用“ +=” 运算符。

Page 237: 第 1 章   C# 入门基础

C#从入门到实践

12.2.3 移除事件

除了注册事件之外,还可以移除事件。移除事件使用“ -=”运算符。

Page 238: 第 1 章   C# 入门基础

C#从入门到实践

12.2.4 调用事件

声明一个事件之后,如果没有向该事件注册方法,那么该事件的值为空( null )。因此,在调用事件时,往往需要检查该事件是否为空。

Page 239: 第 1 章   C# 入门基础

C#从入门到实践

12.3 实例一:测试打印事件

【实例 12-1】演示了测试打印事件的方法。该功能由TestPrintEvent 类和 PrintEventHandler 委托实现。

Page 240: 第 1 章   C# 入门基础

C#从入门到实践

12.4 小结

本章主要介绍了 C# 语言中的委托和事件,如声明委托、委托实例化、委托调用、声明事件、注册事件、移除事件、调用事件等。其中,读者要着重掌握声明委托、委托调用、声明事件、注册事件和调用事件,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的异常处理。

Page 241: 第 1 章   C# 入门基础

C#从入门到实践

12.5 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_12” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ PrintEventHandler” 的委托,并使

用该委托定义名称为“ PrintEvent” 的事件,然后测试该事件的使用方法。

Page 242: 第 1 章   C# 入门基础

C#从入门到实践

第 13 章 异常处理

异常是程序执行时遇到的任何错误情况或意外行为。应用程序必须能够统一处理在执行期间发生的错误。 .NET Framework 公共语言运行库提供了一个模型,以统一的方式通知程序发生的错误。本章将讲解 C# 语言中的异常处理机制,主要介绍以下知识点。

异常概述; try 语句; System.Exception 类; .NET Framework 常用异常类; 创建自定义异常类。

Page 243: 第 1 章   C# 入门基础

C#从入门到实践

13.1 异常概述

和 C++ 程序语言一样, C# 程序语言也存在异常处理机制。 C# 程序语言中的异常用于处理系统级和应用程序级的错误状态,它是一种结构化的、统一的和类型安全的处理机制。

Page 244: 第 1 章   C# 入门基础

C#从入门到实践

13.1.1 导致异常的原因

在应用程序运行时,发生异常的原因是多种多样的,如除数为 0 、堆栈溢出等。导致异常的原因可以归纳为以下 2 大类。

在执行语句和表达式( C# 语言)的过程中,有时会出现一些例外情况,从而使得某些操作无法正常完成,此时就会引发一个异常。

应用程序使用 throw 语句特意产生一个异常,此时将引发一个异常。

Page 245: 第 1 章   C# 入门基础

C#从入门到实践

13.1.2 try 语句

try 语句可以用来捕捉在代码块的执行期间发生的各种异常。它可以包含 try块、 catch块和 finally块,具体说明如下。

try块,一般包含有可能发生异常的代码。 catch块,包含出现异常时需要执行的响应代码。 finally块,包含出现异常时一定执行的代码,如资源清理

等操作。

Page 246: 第 1 章   C# 入门基础

C#从入门到实践

13.1.3 异常处理

异常是由 try 语句处理的。当发生异常时,系统将搜索与当前 try块相关的最近的、可以处理该异常的 catch块,然后由该 catch块处理该异常。如果与当前 try块相关的所有 catch块都不能处理该异常,则沿着堆栈向上搜索封闭该异常代码的 try块及其相关联的 catch块,如果找到,则由该 catch块处理该异常。如果还没有找到 catch块,则重复上述过程,直到找到 catch块。如果到达调用堆栈顶部仍然没有找到处理该异常的 catch块,则由默认的异常处理程序处理该异常,然后应用程序终止。

Page 247: 第 1 章   C# 入门基础

C#从入门到实践

13.2 System.Exception 类

System.Exception 类表示在应用程序执行期间发生的错误,它是 .NET Framework 中所有异常的基类型。当系统或应用程序发生错误时,将通过引发包含错误信息的异常来报告错误。一旦异常发生后,将由该应用程序或默认异常处理程序(如 System.Exception 类)来处理异常。

System.Exception 类包含描述错误的可读文本。当异常发生时,应用程序的运行库(如 .NET Framework )将产生消息(保存在 Exception 类的实例的 Message属性中)通知用户错误的性质并提供解决该问题的操作建议。 Exception 类包括以下两类异常。

从 SystemException 派生的预定义公共语言运行库异常类。从 ApplicationException 派生的用户定义的应用程序异常类

Page 248: 第 1 章   C# 入门基础

C#从入门到实践

13.3 常用异常类

.NET Framework 提供了 10 个常用异常类,如处理空( null )引用的System.NullReferenceException 类、处理数组索引小于 0 或超过其下标的 System.IndexOutOfRangeException 类等。这些常用异常类及其说明如表 13.3所示。类 描述

System.NullReferenceException 如果使用 null引用,引发此异常。

System.IndexOutOfRangeException 如果使用小于零或超出数组界限的下标访问数组时,引发该异常。

System.InvalidCastException 如果显式转换失败时,就会引发此异常。

System.DivideByZeroException 当除数为 0时,引发该异常。

System.StackOverflowException 当堆栈溢出(如无限递归)时,引发该异常。

System.OverflowException 在 checked上下文中的算术运算溢出时,引发该异常。

System.OutOfMemoryException 在通过 new操作分配内存失败时,引发该异常。

System.ArithmeticException 在算术运算期间发生错误时,引发该异常。

System.TypeInitializationException 静态构造函数引发异常,且没有可以捕捉到它的 catch子句时,引发该异常。

System.ArrayTypeMismatchException 如果被存储的元素的实际类型与数组的元素类型不兼容时,引发此异常。

Page 249: 第 1 章   C# 入门基础

C#从入门到实践

13.4 实例一:自定义异常处理类

本实例创建了一个自定义异常处理类,它的名称为CustomException ,并直接继承于 System.Exception类。 CustomException 类声明了一个名称为 ErrorCode的属性,表示错误代码。因此,使用 CustomException类处理异常,可以为异常添加错误代码。

Page 250: 第 1 章   C# 入门基础

C#从入门到实践

13.4.1 设计 CustomException 类

CustomException 类包含 1 个字段: errorCode ,表示错误代码,类型为 int 。程序代码如下。

public class CustomException:System.Exception

{

private int errorCode = 10001;

Page 251: 第 1 章   C# 入门基础

C#从入门到实践

13.4.2 使用 CustomException 类处理异常

【实例 13-1】使用 CustomException 类处理异常,并介绍了使用 CustomException 类产生异常并捕获该类产生异常的方法。

Page 252: 第 1 章   C# 入门基础

C#从入门到实践

13.5 小结

本章主要介绍了 C# 语言中的异常,如异常概述、 try 语句、 System.Exception 类、 .NET Framework 常用异常类、自定义异常类等。其中,读者要着重掌握 try 语句,以及处理异常的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的泛型。

Page 253: 第 1 章   C# 入门基础

C#从入门到实践

13.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_13” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ MyException” 的类(继承于

Exception ),并使用该类处理自定义的异常。

Page 254: 第 1 章   C# 入门基础

C#从入门到实践

第 14 章 泛型

泛型( Generic)是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型和其方法的参数类型出现。泛型方法可以将其类型参数用作其返回值的类型或者其形参的类型之一。本章将讲解 C#语言中的泛型,主要介绍以下知识点 。

泛型概述; 泛型方法; 创建泛型列表 创建泛型堆栈。

Page 255: 第 1 章   C# 入门基础

C#从入门到实践

14.1 泛型概述

使用过 C++ 模板的读者可能熟悉泛型( Generic )这一概念。 C# 中的泛型能够将类型作为参数来传递,即在创建类型时,事先使用一个特定的符号(如 T 等)代替实际的类型,在创建该类型的实例时,才指定 T 的实际类型。

泛型可以让类、结构、接口、委托和方法按它们存储和操作的数据的类型进行参数化。泛型能提供更强的编译时类型检查,减少数据类型之间的显式转换,以及装箱操作和运行时的类型检查。

使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。泛型最常见的用途是创建集合类。 .NET Framework 类库在 System.Collections.Generic命名空间中包含多个新的泛型集合类,如List<T>、 Stack<T>、 Queue<T> 等。当然,开发人员也可以创建自定义泛型类型。

Page 256: 第 1 章   C# 入门基础

C#从入门到实践

14.1.1 泛型类声明

泛型类声明也是一种类的声明,因此,泛型类声明也遵循类声明的规则。一个泛型类一般至少包含一个类型形参( 14.1.2 小节中介绍)。当创建该泛型类的实例时,需要指定该类型形参的具体类型。

Page 257: 第 1 章   C# 入门基础

C#从入门到实践

14.1.2 类型形参

类型形参放置在类名后,并在“ <” 和“ >”分隔符中指定。类型形参仅仅是一个简单标识符,是将来提供的类型的形式占位符。换句话说, T 类型形参只起占位符的作用,直到在使用时才为其指定了实际类型。

每一个类型形参所代表的实际类型由其所在实例创建时指定。特别地,该实例将存储类型形参的数据而不进行数据类型转换。

Page 258: 第 1 章   C# 入门基础

C#从入门到实践

14.1.3 类型形参的约束

通常地,类型形参的类型可以指定为任何类型。然而,一些类型形参需要指定一定种类的类型,如结构、类等。为了实现该功能,就需要限制类型形参的类型,这种限制被称为约束。即在定义泛型类时,可以限制在实例化类时用于类型参数的类型种类。如果尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。

Page 259: 第 1 章   C# 入门基础

C#从入门到实践

14.1.4 泛型类的成员

泛型类的所有成员都可以直接使用其所属类的类型形参。在运行时,类型形参都被替换为相应的实际类型(该类型在创建类的实例时指定)。

Page 260: 第 1 章   C# 入门基础

C#从入门到实践

14.1.5 泛型类的静态字段

在泛型类中,静态字段的共享方法比较特殊,即只有在具有相同类型形参的类型的实例才能够共享同一个静态字段的值。

Page 261: 第 1 章   C# 入门基础

C#从入门到实践

14.2 泛型方法

泛型方法( Generic Method )是使用类型参数声明的方法,它可以声明在类、结构或接口中,而这些类、结构或接口本身可以是泛型或非泛型的。如果这些类、结构或接口也是泛型类型时,那么在这些方法内既可以引用该泛型方法的类型形参,也可以使用这些类、结构或接口的类型形参。

Page 262: 第 1 章   C# 入门基础

C#从入门到实践

14.2.1 声明泛型方法

和普通方法相比,除了普通的参数之外,泛型方法还必须包含类型形参,即泛型方法是指在声明中包含类型形参的方法。

Page 263: 第 1 章   C# 入门基础

C#从入门到实践

14.2.2 调用泛型方法

泛型方法调用可以显式指定类型实参列表,或者可以省略类型实参列表并依赖类型推断确定类型实参。通常地,调用泛型方法和调用普通方法一样,但需要为类型形参提供相应的类型实参列表。

Page 264: 第 1 章   C# 入门基础

C#从入门到实践

14.2.3 通过委托调用泛型方法

除了 14.3.2 中调用泛型方法的方法之外,还可以通过委托来调用泛型方法。

Page 265: 第 1 章   C# 入门基础

C#从入门到实践

14.2.4 虚泛型方法

和普通方法一样,泛型方法也存在虚泛型方法,它也可以使用 abstract、 virtual和 override修饰符进行声明。

Page 266: 第 1 章   C# 入门基础

C#从入门到实践

14.3 实例一:实现泛型列表

本实例首先创建了名称为“ GenericList<T>” 的泛型类(保存在 GenericList.cs文件中),并为该类提供 5 个方法:Add(T item)、 Remove(T item)、 RemoveAt(int index)、 Clear()和 Sort(IComparer<T> c) ;然后创建该类的实例 list ,并介绍了 GenericList<T> 类的属性和方法的使用方法。

Page 267: 第 1 章   C# 入门基础

C#从入门到实践

14.3.1 设计泛型列表类 GenericList<T>

GenericList<T> 泛型类为 T 类型形参添加了约束“ where T:IComparable” ,即约束 T 类型形参的类型必须实现IComparable 接口。 GenericList<T> 泛型类包含 list字段,表示一个列表,类型为 List<T> 。程序代码如下。

public class GenericList<T> where T:IComparable

{

/// <summary> 私有字段 list ,类型为 List<T> </summary>

private List<T> list;

Page 268: 第 1 章   C# 入门基础

C#从入门到实践

14.3.2 测试泛型列表

【实例 14-1】测试 GenericList<T> 类,并创建了该类的实例 list 。

Page 269: 第 1 章   C# 入门基础

C#从入门到实践

14.4 实例二:实现泛型堆栈

本实例首先创建了名称为“ GenericStack<T>” 的泛型类(保存在 GenericStack.cs文件中),并为该类提供 5 个方法: IsEmpty()、 Push(T item)、 Pop()、 Peek()和Clear() ;然后创建该类的实例 stack ,并介绍了GenericStack<T> 类的属性和方法的使用方法。

Page 270: 第 1 章   C# 入门基础

C#从入门到实践

14.4.1 设计泛型堆栈类GenericStack<T>

GenericStack<T> 泛型类为 T 类型形参添加了约束“ where T:class” ,即约束 T 类型形参的类型必须为引用类型。 GenericStack<T> 泛型类包含 stack字段,表示一个堆栈,类型为 Stack<T> 。

Page 271: 第 1 章   C# 入门基础

C#从入门到实践

14.4.2 测试泛型堆栈

【实例 14-2】测试 GenericStack<T> 类,并创建了该类的实例 stack 。

Page 272: 第 1 章   C# 入门基础

C#从入门到实践

14.5 小结

本章主要介绍了 C# 语言中的泛型,如泛型概述、泛型方法、泛型列表、泛型堆栈等。其中,读者要着重掌握泛型概述,以及创建泛型类(如泛型列表、泛型堆栈等)的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍C# 语言中的分部类型和可空类型。

Page 273: 第 1 章   C# 入门基础

C#从入门到实践

14.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_14” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ MyGenericStack” 的泛型堆栈,同

时实现堆栈的常用操作,如入栈、出栈、堆栈是否为空等。

Page 274: 第 1 章   C# 入门基础

C#从入门到实践

第 15 章 分部类型和可空类型

分部类型可以将类、结构、接口或者方法的定义拆分为一个或多个部分,甚至可以保存为多个源文件中。可空类型可以用来处理值类型的值为空的情况,它能够指示可空类型的实例是否包含一个确定的值。本章将讲解 C# 语言中的分部类型和可空类型,主要介绍以下知识点。

声明分部类、结构和接口;分部类型同名成员处理;处理分部类型的基接口; 可空类型的属性; 可空类型的方法; bool? 类型。

Page 275: 第 1 章   C# 入门基础

C#从入门到实践

15.1 分部类型

分部类型( Partial type )允许将类、结构和接口划分为多个部分,并存储在不同的源文件中,以便于开发和维护。在 Visual Studio 2008 集成开发环境中开发应用程序时,有时一个类(如Windows 窗体、 ASP.NET 窗体页等)的一部分代码由机器自动生成,另外一部分代码由程序员编写。如果把这个类设置为分部类,那么这两部分代码可以保存在不同的源文件中,从而增加了应用程序的代码的灵活性。

在声明分部类型的每一个部分时,每一个部分都必须包含 partial修饰符,并且分部类型的所有声明代码都必须位于同一命名空间中。 partial修饰符表示它所在的类型可能还包含其他部分,但是其他部分并不一定是必须的。如果一个类型只包含一个部分,在声明该类型时使用了 partial修饰符,也是正确的。

Page 276: 第 1 章   C# 入门基础

C#从入门到实践

15.1.1 声明分部类

使用 partial修饰符可以用来声明分部类。

Page 277: 第 1 章   C# 入门基础

C#从入门到实践

15.1.2 声明分部结构

使用 partial修饰符可以用来声明分部结构。

Page 278: 第 1 章   C# 入门基础

C#从入门到实践

15.1.3 声明分部接口

使用 partial修饰符除了可以用来声明分部类和结构之外,还可以用来声明接口。

Page 279: 第 1 章   C# 入门基础

C#从入门到实践

15.1.4 同名成员处理

如果一个分部类型包含了多个部分,那么该类型的所有成员为各个部分成员的并集,并且在每一个部分中可以访问其他部分的成员,即使在声明该成员时使用了 private修饰符。然而,在不同部分中声明了同一个名称的成员,则发生编译时错误。除非该成员使用了 partial修饰符。

Page 280: 第 1 章   C# 入门基础

C#从入门到实践

15.1.5 处理基接口

如果一个分部类型包含了多个部分,那么该类型的所有基接口集是每一个部分指定的基接口的并集。一个基接口在分部类型的一个部分中只能指定一次,但是可以在多个部分中同时被指定,即多个部分可以同时指定同一个基接口。

注意:在整个分部类型中,一个基接口的成员的实现只能是一个。但是,一个部分的基接口可以由另外一个部分提供该基接口的实现。

Page 281: 第 1 章   C# 入门基础

C#从入门到实践

15.2 可空类型

可空类型( Nullable )是一个组合了基础类型的值和布尔空值指示符的结构。可空类型除了表示基础类型的所有值之外,还可以表示空值( null )。可空类型为值类型,声明可空类型存在以下两种形式。

( 1 )使用 System.Nullable 类声明可空类型( 2 )使用 ? (问号)声明可空类型

Page 282: 第 1 章   C# 入门基础

C#从入门到实践

15.2.1 HasValue和 Value属性

任何可空类型的实例都包含两个公共只读属性: HasValue和 Value 。它们的具体意义说明如下。

HasValue属性的类型为 bool ,它表示该实例是否包含一个确定值。如果 HasValue属性的值为 true ,则表示该实例包含一个确定的值。否则,表示该实例为空,即它不包含确定的值。此时,如果要获取该实例的值,则发生运行时错误。

Value属性的类型为该可空类型的基础类型,它表示该实例的一个确定的值,并作为该实例的值。

Page 283: 第 1 章   C# 入门基础

C#从入门到实践

15.2.2 GetValueOrDefault() 方法

可空类型的实例只包含一个方法: GetValueOrDefault() ,它可以用来获取可空类型的实例的值或默认值。它存在以下两种重载形式。

( 1) public T GetValueOrDefault()

( 2) public T GetValueOrDefault(T defaultValue)

T 表示可空类型的基础类型。如果可空类型的实例的HasValue属性的值为 true ,则该方法返回该实例的值(即 Value属性的值)。如果可空类型的实例的 HasValue属性的值为 false ,( 1 )方法返回该实例的默认值,( 2 )方法返回 defaultValue参数的值。

Page 284: 第 1 章   C# 入门基础

C#从入门到实践

15.2.3 bool? 类型

bool? 类型为可空布尔类型,它可以表示 3 个值: true、 false和null 。可空布尔类型提供了两个运算符: &和 |。& 运算符表示逻辑与, | 运算符表示逻辑或。可空布尔类型的实例运算结果如表 15.1所示。

X Y X & Y X | Y

true true true true

true false false true

true null null true

false true false true

false false false false

false null false null

null true null true

null false false null

null null null null

Page 285: 第 1 章   C# 入门基础

C#从入门到实践

15.3 实例一:测试可空类型

【实例 15-1】演示了测试基类型为 int 的可空类型的方法。该功能由 TestNullableType 类实现。

Page 286: 第 1 章   C# 入门基础

C#从入门到实践

15.4 小结

本章主要介绍了 C# 语言中的分部类型和可空类型,如声明分部类、结构和接口、分部类型同名成员处理、处理分部类型的基接口、可空类型的属性、可空类型的方法、 bool? 类型等。其中,读者要着重掌握数组声明分部类和使用可空类型的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的隐型变量、初始化器、匿名类型和隐型数组。

Page 287: 第 1 章   C# 入门基础

C#从入门到实践

15.5 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_15” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个名称为“ UsingStringNull” 的类,并在该类处理可以为空的字符串。

Page 288: 第 1 章   C# 入门基础

C#从入门到实践

第 16 章 隐型变量、初始化器、匿名类型和隐型数组

隐型局部变量是使用 var 关键字声明的一种隐藏类型的局部变量。初始化器包括对象初始化器和集合初始化器,它们分别用来初始化对象和集合。使用 new 运算符和匿名对象初始化器可以创建一个匿名类型的对象;使用 var 关键字和匿名数组初始化器可以创建一个隐型数组。本章将讲解 C# 语言中的隐型局部变量、对象初始化器、集合初始化器、匿名类型和隐型数组,主要介绍以下知识点。

声明隐型局部变量; 使用隐型局部变量; 对象初始化器; 集合初始化器;匿名类型;隐型数组。

Page 289: 第 1 章   C# 入门基础

C#从入门到实践

16.1 隐型局部变量

顾名思义,隐型( implicitly typed )局部变量是一个局部变量,而且它的类型被隐藏了。在隐型局部变量声明中,正被声明的局部变量的类型可以从初始化该变量的表达式推导出来。

Page 290: 第 1 章   C# 入门基础

C#从入门到实践

16.1.1 声明隐型局部变量

声明隐型局部变量需要使用 var 关键字,并使用 var 关键字作为变量的类型。在声明隐型局部变量时,不明确指定该变量的类型,而是使用 var 关键字指定变量的类型。该变量的实际类型将在其初始化表达式中推导出来。

Page 291: 第 1 章   C# 入门基础

C#从入门到实践

16.1.2 使用隐型局部变量

使用隐型局部变量可以不显式指定变量的类型,从而简化了程序代码。然而,如果大量使用隐型局部变量,往往可能造成程序代码难以理解和阅读。因此,只有在适当的时候使用隐型局部变量,才是一个比较好的选择。隐型局部变量比较适合以下 4 种场景。

1 .声明隐型局部变量2. for 语句中3. foreach 语句中4. using 语句中

Page 292: 第 1 章   C# 入门基础

C#从入门到实践

16.2 对象初始化器

对象初始化器( object initializer )又称为对象初始值设定项,它可以为某个对象的零个或多个字段或属性指定值。即对象初始化器不显式调用该对象类型的构造函数,就能够创建该对象类型的实例。

对象初始化器包含一组成员初始值设定项。这一组设定项由“ {” 和“ }” 包围,各个设定项之间用 , (逗号)分隔。每一个成员初始值设定项都为一个赋值表达式,表达式的左边为成员的名称,表达式的右边是一个可计算的表达式。“ ID = 1” 表达式就是一个成员初始值设定项,“ {ID = 1,Name = "Zhangsan"}” 表达式就是一组设定项。

Page 293: 第 1 章   C# 入门基础

C#从入门到实践

16.3 集合初始化器

集合初始化器( collection initializer )又称为集合初始值设定项,它可以用来设置集合中的元素。集合初始化器包含一组元素初始值设定项。这一组设定项由“ {” 和“ }” 包围,各个设定项之间用 , (逗号)分隔。每一个元素初始值设定项指定一个元素,“ {1,2,3,4,5,6,7,8,9}” 表达式就是一组元素初始值设定项。

Page 294: 第 1 章   C# 入门基础

C#从入门到实践

16.4 匿名类型

顾名思义,匿名类型是一种隐藏了类型名称的类型,它由new 运算符和匿名对象初始化器共同实现。即使用 new运算符和匿名对象初始化器可以创建一个新的对象,这个新创建的对象就是一个匿名类型的对象。其中,把 new运算符和匿名对象初始化器组成的表达式又称为匿名对象创建表达式。

Page 295: 第 1 章   C# 入门基础

C#从入门到实践

16.5 隐型数组

隐型数组和匿名类型比较相似。和匿名类型的匿名对象初始化器一样,匿名数组也存在一个匿名数组初始化器。匿名对象初始化器一般用于创建一个匿名类型的对象,匿名数组初始化器用来创建一个匿名数组。

匿名数组由 var 关键字和匿名数组初始化器共同创建,而且匿名数组初始化器中的元素类型都必须能够隐式转换为同一个类型(不能为 null )。即对于匿名数组初始化器而言,会存在一种类型(不能为 null ),使得该匿名数组初始化器中所有元素都能够转换为该类型的元素。

Page 296: 第 1 章   C# 入门基础

C#从入门到实践

16.6 实例一:在 foreach 语句中使用隐型局部变量

【实例 16-1】在 foreach 语句中使用隐型局部变量遍历元素类型为 string 的数组中的每一个元素。该功能由 VarForeach()静态方法实现。

Page 297: 第 1 章   C# 入门基础

C#从入门到实践

16.7 小结

本章主要介绍了 C# 语言中的隐型变量、初始化器、匿名类型和隐型数组,如声明隐型局部变量、使用隐型局部变量、对象初始化器、集合初始化器、匿名类型、隐型数组等。其中,读者要着重掌握声明隐型局部变量和使用隐型局部变量,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的迭代器、匿名方法和扩展方法。

Page 298: 第 1 章   C# 入门基础

C#从入门到实践

16.8 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_16” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )在该应用程序中使用隐型数组计算 0~100 (共 101 个

整数)的和。

Page 299: 第 1 章   C# 入门基础

C#从入门到实践

第 17 章 迭代器、匿名方法和扩展方法

迭代器是一个语句块,它可以产生一系列有序值,从而使得foreach 语句可以访问该序列。匿名方法是一种特殊的方法,它由 delegate 关键字、参数列表(可选)和包含在“ {” 和“ }”分隔符中的语句列表组成,并省略了方法的名称。扩展方法可以向现有的类型“添加”新的方法,它是一种静态方法,通过扩展类型的实例来调用扩展方法。本章将讲解 C# 语言中的迭代器、匿名方法和扩展方法,主要介绍以下知识点。

创建非泛型和泛型迭代器;非泛型和泛型枚举器; 创建匿名方法; 将匿名方法作为参数传递;声明扩展方法; 调用扩展方法。

Page 300: 第 1 章   C# 入门基础

C#从入门到实践

17.1 迭代器

迭代器( iterator )是一个产生( yield )有序值序列的语句块( block )。它也可以通过 yield 关键字对数组或集合类执行自定义迭代。迭代器包含以下两个特有的语句。

yield return 语句,产生迭代的下一个值。yield break 语句,指示迭代完成。当迭代器执行到 yield return 语句时,迭代器会保存当前位

置。如果该迭代器再一次被调用时,该迭代器将从上述保存的位置重新开始执行。迭代器可以产生一系列的值,而且所有值的类型均相同,该类型称为迭代器的返回类型,又称为产生类型。

Page 301: 第 1 章   C# 入门基础

C#从入门到实践

17.1.1 创建非泛型迭代器

IEnumerable 接口表示公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。 IEnumerable 接口只包含GetEnumerator() 方法,它返回一个循环访问集合的枚举数。创建一个非泛型迭代器最常用的方法是实现IEnumerable 接口的 GetEnumerator() 方法。

Page 302: 第 1 章   C# 入门基础

C#从入门到实践

17.1.2 创建泛型迭代器

如果要创建一个泛型迭代器,往往需要实现 IEnumerable和IEnumerable<T> 接口的 GetEnumerator() 方法。

Page 303: 第 1 章   C# 入门基础

C#从入门到实践

17.1.3 IEnumerator和IEnumerator<T> 接口

IEnumerator 表示枚举器的非泛型接口,支持对非泛型集合的简单迭代。 IEnumerator<T> 表示枚举器的泛型接口,支持泛型集合的简单迭代。

1. IEnumerator 接口2. IEnumerator<T> 接口

Page 304: 第 1 章   C# 入门基础

C#从入门到实践

17.2 匿名方法

顾名思义,匿名方法( anonymous method )是一种隐藏了名称的方法。在 C# 2.0 版本之前,声明委托的唯一方法是使用命名方法,即方法必须指定其名称。 C# 2.0引入了匿名方法实现了同样的功能, C# 3.0及其以上版本,使用 Lambda 表达式(第 18 章)取代了匿名方法,它比匿名方法更加简洁。

匿名方法允许与委托关联的代码以“内联”方式写入使用委托的位置,从而方便地将代码直接“绑定”到委托实例。

Page 305: 第 1 章   C# 入门基础

C#从入门到实践

17.2.1 创建匿名方法

匿名方法由 delegate 关键字、参数列表(可选)和包含在“ {” 和“ }”分隔符中的语句列表组成。从匿名方法的组成元素可以看到,匿名方法已经省略了该方法的名称。

Page 306: 第 1 章   C# 入门基础

C#从入门到实践

17.2.2 将匿名方法作为参数传递

正是因为匿名方法允许与委托关联的代码以“内联”方式,从而使得可以将匿名方法作为方法的参数来传递。

Page 307: 第 1 章   C# 入门基础

C#从入门到实践

17.3 扩展方法

扩展方法可以使得开发人员能够向现有类型“添加”新的方法,而且不需要创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种静态方法,可以通过扩展类型的实例来调用扩展方法。

Page 308: 第 1 章   C# 入门基础

C#从入门到实践

17.3.1 声明扩展方法

声明扩展方法时,需要使用 this修饰符。扩展方法的第一个参数指定该方法所作用的类型,并使用 this修饰符作为该参数的前缀。

Page 309: 第 1 章   C# 入门基础

C#从入门到实践

17.3.2 导入扩展方法

导入扩展方法比较简单,只要使用 using指令引入扩展方法所在的命名空间即可。实际上,被导入的扩展方法作为其第一个参数的类型上的附加方法。

Page 310: 第 1 章   C# 入门基础

C#从入门到实践

17.3.3 调用扩展方法

使用 using指令导入 ToInt32(this string str)扩展方法之后,就可以调用该扩展方法了。

Page 311: 第 1 章   C# 入门基础

C#从入门到实践

17.4 实例一:扩展 string 类型的方法

【实例 17-1】为 string 类型扩展了一个方法,该方法的名称为“ ToInt32(this string str)” ,它可以将一个字符串转换为一个整数。

Page 312: 第 1 章   C# 入门基础

C#从入门到实践

17.5 小结

本章主要介绍了 C# 语言中的迭代器、匿名方法和扩展方法,如创建非泛型和泛型迭代器、非泛型和泛型枚举器、创建匿名方法、将匿名方法作为参数传递、声明扩展方法、调用扩展方法等。其中,读者要着重掌握创建非泛型和泛型迭代器和创建匿名的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的 Lambda 表达式和查询表达式。

Page 313: 第 1 章   C# 入门基础

C#从入门到实践

17.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_17” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )在该应用程序中创建一个泛型迭代器,并使用该迭代

器。

Page 314: 第 1 章   C# 入门基础

C#从入门到实践

第 18 章 Lambda 表达式和查询表达式

C# 提供了一种可以用来查询集合、 XML、 DataSet (数据集)和数据库的技术,并使用 Lambda 表达式和查询表达式实现这种查询技术。 Lambda 表达式其实是一种简写的匿名函数,它可以包含表达式和 C# 语句。查询表达式是一种使用查询语法表示的表达式,它可以从一个或多个给定的数据源中检索数据,并指定检索结果的表现形式。本章将讲解 C# 语言中的 Lambda 表达式和查询表达式,主要介绍以下知识点。

Lambda 表达式; from子句;select子句; where子句;let子句; orderby子句;group子句; into子句;join子句。

Page 315: 第 1 章   C# 入门基础

C#从入门到实践

18.1 Lambda 表达式

和匿名方法一样, Lambda 表达式也是一种匿名函数( anonymous function ),它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。但是, Lambda 表达式比匿名方法具有更加简洁的表示形式。 Lambda 表达式可以由输入参数、 Lambda 运算符和表达式(或语句块)构成,它的语法形式如下。

(input parameters) => expression;

input parameters 表示输入参数,它是可选的;“ =>”为Lambda 运算符(读作“ goes to” ); expression 表示表达式或语句块。

Page 316: 第 1 章   C# 入门基础

C#从入门到实践

18.1.1 输入参数

在 Lambda 表达式中,输入参数是 Lambda 运算符的左边部分。它包含参数的数量可以为 0, 1 或者多个。当输入参数的数量为 0 时, Lambda 表达式的左边部分的一对小括弧不能被省略。

Page 317: 第 1 章   C# 入门基础

C#从入门到实践

18.1.2 表达式或语句块

在 Lambda 表达式中, Lambda 运算符的右边部分可以是一个表达式或由多个表达式组成的语句块。

Page 318: 第 1 章   C# 入门基础

C#从入门到实践

18.2 查询表达式

查询表达式( Query expression )是一种使用查询语法表示的表达式,由一组类似与 SQL或 XQuery 的声明性语法编写的子句组成。每一个子句可以包含一个或多个 C# 表达式,这些 C# 表达式本身也可能是查询表达式或包含查询表达式。查询表达式包括 8 个基本子句,具体说明如下。

from子句 select子句where子句 let子句orderby子句 group子句into子句 join子句查询表达式必须以 from子句开头,以 select或 group子句

结束。在第一个 from子句和最后一个 select子句或group子句之间,可以包含一个或多个 where子句、 let子句、 join子句、 orderby子句和 group子句,甚至还可以是 from子句。

Page 319: 第 1 章   C# 入门基础

C#从入门到实践

18.2.1 from子句

任何一个查询表达式,不管是否为子查询表达式,它必须包含 from子句,且以 from子句开头。 from子句用来指定查询表达式的数据源和范围变量。数据源不但可以包括查询本身的数据源,而且还可以包括子查询的数据源。范围变量用来表示数据源序列中的每一个元素。

1 .数据源2 .包含单个 from子句的查询表达式3 .包含多个 from子句的查询表达式4 .包含复合 from子句的查询表达式

Page 320: 第 1 章   C# 入门基础

C#从入门到实践

18.2.2 select子句

select子句指定查询结果的类型和表现形式,即指定将在执行查询时产生的值的类型。 select子句结果及其表现形式与其前面所有子句的计算结果,以及本身中的所有表达式相关。一个查询表达式要么以 select子句结束,要么以group子句结束。

Page 321: 第 1 章   C# 入门基础

C#从入门到实践

18.2.3 where子句

where子句指定筛选元素的逻辑条件,即用来确定从查询表达式中选择哪些元素。 where子句由一个或多个布尔表达式,以及逻辑运算符(如逻辑与、逻辑或等)组成。一个查询表达式可以包含一个或多个 where子句。在查询表达式中, where子句不能出现在查询表达式的第一个子句或最后一个子句的位置,其他任何位置都可以放置 where子句。

Page 322: 第 1 章   C# 入门基础

C#从入门到实践

18.2.4 let子句

let子句可以创建一个新的范围变量,用来保存查询表达式中的中间结果。 let子句创建的范围变量是一个只读变量,它的值只能通过初始化操作赋值。一旦设定了范围变量的值之后,它的值将不能被修改。当然,可以查询该范围变量的值。

Page 323: 第 1 章   C# 入门基础

C#从入门到实践

18.2.5 orderby子句

orderby子句可以对查询结果进行排序,排序方式为“升序”(由 ascending 关键字指定)和“降序”(由descending 关键字指定)。

Page 324: 第 1 章   C# 入门基础

C#从入门到实践

18.2.6 group子句

group子句(使用 by 关键字)可以对查询的结果进行分组,并返回元素类型为 IGrouping<TKey, TElement> 的序列。其中, TKey 为分组中键的类型, TElement 为分组中元素的类型。

Page 325: 第 1 章   C# 入门基础

C#从入门到实践

18.2.7 into子句

into子句可以创建一个临时标识符,并用来保存 group子句、 join子句或 selet子句的结果,以供其他子句查询该结果。有时,称在 group或 select子句中使用新标识符的用法为“延续”。

Page 326: 第 1 章   C# 入门基础

C#从入门到实践

18.2.8 join子句join子句是查询表达式中比较复杂的一个子句,它和 SQL

语句中的 JOIN子句比较相似,可以用来联接两个数据源,即设置两个数据源之间的关系。一般情况下,这两个数据源是存在相关联的属性或值,以供这两个数据源中的元素进行比较。特别地, join子句可以使用 equals 关键字比较元素的指定属性是否相等。 join子句支持以下 3 种常见联接方式。

内部联接,元素的联接关系必须同时满足两个数据源,类似于 SQL 语句中的 INNER JOIN子句。

分组联接,包含 into子句的 join子句。左外部联接,元素的联接关系必须满足联接中的左数据源

,类似于 SQL 语句中的 LEFT JOIN子句。

Page 327: 第 1 章   C# 入门基础

C#从入门到实践

18.3 实例一:使用 Lambda 表达式查询XML

【实例 18-1】在 QueryXml() 方法中介绍使用 Lambda 表达式查询 XML 类的方法。

Page 328: 第 1 章   C# 入门基础

C#从入门到实践

18.4 小结

本章主要介绍了 C# 语言中的查询表达式,如 Lambda 表达式、 from子句、 select子句、 where子句、 let子句、 orderby子句、 group子句、 into子句、 join子句等。其中,读者要着重掌握 Lambda 表达式,以及使用Lambda 表达式查询集合、 XML文件的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍使用 C# 语言处理字符串的方法。

Page 329: 第 1 章   C# 入门基础

C#从入门到实践

18.5 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_18” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )创建一个查询表达式,并使用该查询表达式从一段文

本中查询所有单词。

Page 330: 第 1 章   C# 入门基础

C#从入门到实践

第 19 章 字符串处理

字符串类型是 C# 编程语言中最为常用的一种数据类型 ,.NET Framework 为字符串提供了丰富地操作和处理方法。通过这些方法,开发人员可以轻松简单地处理字符串。本章将讲解 .NET Framework 中处理字符串的方法,主要介绍以下知识点。

String 类; StringBuilder 类; 不变字符串处理; 可变字符串处理。

Page 331: 第 1 章   C# 入门基础

C#从入门到实践

19.1 String和 StringBuilder 类

在 .NET Framework 中,字符串可以分为两种类型:不变字符串(由 String 类表示)和可变字符串(由StringBuilder 类表示)。不变字符串一旦被创建,那么它的内容是不能被修改的;而可变字符串被创建之后,它的内容是可以动态修改的。

Page 332: 第 1 章   C# 入门基础

C#从入门到实践

19.1.1 String 类

String 类表示一系列的有序 Unicode字符,用来表示文本。 String 对象是字符( Char 对象)的有序集合,用来表示字符串。 String 对象的值是该有序集合的内容,并且该值是不可变的,即一旦创建了一个 String 对象,那么就不能修改该对象的值。虽然有些方法看起来修改了String 对象,而实际上是返回了一个包含修改后内容的新的 String 对象。

Page 333: 第 1 章   C# 入门基础

C#从入门到实践

19.1.2 StringBuilder 类

StringBuilder 类表示可变字符串,可以创建能够动态修改(如追加、移除、替换、插入等)的字符串对象。

Page 334: 第 1 章   C# 入门基础

C#从入门到实践

19.2 不变字符串处理

不变字符串(由 String 类表示)是不能被修改的。对不变字符串的每一次处理都将产生一个新的字符串。不变字符串处理的方法主要包括插入字符串、移除字符串、替换字符串、联接字符串、分隔字符串、填充字符串等。下面将详细介绍这些方法。

Page 335: 第 1 章   C# 入门基础

C#从入门到实践

19.2.1 插入字符串

插入字符串是将新的字符串插入到字符串的指定位置,该功能由 String 类的 Insert() 方法实现。 Insert() 方法的原型如下。

public string Insert(int startIndex,string value)

上述方法将 value参数指定字符串插入到字符串的startIndex指定的位置。

startIndex参数表示插入的位置(即索引值), value参数表示被插入的新字符串。上述方法返回一个新的字符串。

Page 336: 第 1 章   C# 入门基础

C#从入门到实践

19.2.2 移除字符串

移除字符串是从字符串中指定位置开始移除其后的所有字符或指定数量的字符,该功能由 String 类的 Remove() 方法实现。 Remove() 方法的原型如下。

public string Remove(int startIndex) ,从 startIndex位置开始移除其后的所有字符。

public string Remove(int startIndex,int count) ,从startIndex位置开始移除其后的数量为 count 的字符。

Page 337: 第 1 章   C# 入门基础

C#从入门到实践

19.2.3 替换字符串

替换字符是指将字符串中指定字符替换为新的字符,或者将指定的字符串替换为新的字符串,该功能由 String 类的Replace() 方法实现。 Replace() 方法的原型如下。

public string Replace(char oldChar,char newChar) ,将字符串中指定字符替换为新的字符。

public string Replace(string oldValue,string newValue) ,将字符串中指定字符串替换为新的字符串。

oldChar参数表示被替换的字符, newChar参数表示替换后的字符。 oldValue参数表示被替换的字符串, newValue参数表示替换后的字符串。

Page 338: 第 1 章   C# 入门基础

C#从入门到实践

19.2.4 联接字符串

联接字符串是将一个或多个字符串对象联接为一个新的字符串,该功能由 String 类的 Concat() 方法或 Join() 方法实现。其中, Concat() 方法的最常用的 4 种原型如下。

public static string Concat(object arg0) ,联接 arg0 对象的字符串表示形式,并创建一个新的字符串。

public static string Concat(string str0,string str1) ,联接str0和 str1字符串,并创建一个新的字符串。

public static string Concat(string str0,string str1,string str2) ,联接 str0、 str1和 str2字符串,并创建一个新的字符串。

public static string Concat(string str0,string str1,string str2,string str3) ,联接 str0、 str1、 str2和 str3字符串,并创建一个新的字符串。

Page 339: 第 1 章   C# 入门基础

C#从入门到实践

19.2.5 分隔字符串

分隔字符串是将一个字符串被指定的分隔字符或字符串分隔为多个子字符串,并返回由子字符串组成的字符串数组。该功能由 String 类的 Split() 方法实现,它的原型如下。

public string[] Split(params char[] separator) 。 public string[] Split(char[] separator,int count) 。 public string[] Split(char[] separator,StringSplitOptions options) 。 public string[] Split(string[] separator,StringSplitOptions options)

。 public string[] Split(char[] separator,int count,StringSplitOptions

options) 。 public string[] Split(string[] separator,int count,StringSplitOptions

options) 。

Page 340: 第 1 章   C# 入门基础

C#从入门到实践

19.2.6 填充字符串

填充字符串是向字符串的指定位置填充指定的字符,该功能由 String 类的 PadRight()和 PadLeft() 方法实现。其中, PadRight() 方法在字符串的右边填充字符, PadLeft() 方法在字符串的左边填充字符串。由于这两个方法比较相似,下面只将介绍 PadLeft() 方法。 PadLeft() 方法的原型如下。

public string PadLeft(int totalWidth) ,在字符串的左边填充空白字符,填充之后,新字符串的总长度为totalWidth

public string PadLeft(int totalWidth,char paddingChar),在字符串的左边填充 paddingChar字符,填充之后,新字符串的总长度为 totalWidth 。

Page 341: 第 1 章   C# 入门基础

C#从入门到实践

19.2.7 查找字符串

查找字符串是指从字符串中查找指定的字符或子字符串。如果找到,则返回第一个匹配字符或字符串的索引;否则返回 -1 。该功能由 String 类的 IndexOf()和 LastIndexOf()方法实现。其中, IndexOf() 方法是从字符串的第一个字符开始依照从头到尾的方式查找, LastIndexOf() 方法从字符串的最后一个字符开始依照从尾到头的方式查找。

Page 342: 第 1 章   C# 入门基础

C#从入门到实践

19.2.8 获取子串

获取子串是指从字符串中获取指定的子字符串,该功能由String 类的 SubString() 方法实现,它的原型如下。

public string SubString(int startIndex) ,获取字符串中从startIndex位置开始的子字符串。

public string SubString(int startIndex,int length) ,获取字符串中从 startIndex位置开始的、最大长度为 length 的子字符串。

Page 343: 第 1 章   C# 入门基础

C#从入门到实践

19.2.9 格式化字符串

格式化字符串是指将字符串转化为指定格式的字符串,该功能由 String 类的 Format() 方法实现。

1 .数字格式化2 .日期和时间格式化

Page 344: 第 1 章   C# 入门基础

C#从入门到实践

19.3 可变字符串处理

可变字符串(由 StringBuilder 类表示)是一种动态字符串,它是可以被动态修改的。动态修改可变字符串的方法主要包括插入字符串、追加字符串、移除字符串、替换字符串、复制字符串等。下面将详细介绍这些方法。

Page 345: 第 1 章   C# 入门基础

C#从入门到实践

19.3.1 插入字符串

插入字符串是将新的字符串插入到字符串的指定位置,该功能由 StringBuilder 类的 Insert() 方法实现。 Insert() 方法存在多种原型,常见的原型如下。

public StringBuilder Insert(int index,string value) ,将value插入到字符串的 index指定的位置。

public StringBuilder Insert(int index,string value,int count) ,将 value插入到字符串的 index指定的位置,并重复执行该超载 count次。

Page 346: 第 1 章   C# 入门基础

C#从入门到实践

19.3.2 追加字符串

追加字符串是指将指定的字符或字符串追加到字符串的末尾,该功能由 StringBuilder 类的Append()、 AppendLine()和 AppendFormat() 方法实现。其中, AppendLine() 方法在追加指定的字符串之后,还追加一个换行符号; AppendFormat() 方法首先格式化被追加的字符串,然后将其追加到字符串。下面仅仅介绍Append() 方法的用法。

Page 347: 第 1 章   C# 入门基础

C#从入门到实践

19.3.3 移除字符串

移除字符串是从字符串中指定位置开始移除其后的指定数量的字符,该功能由 StringBuilder 类的 Remove() 方法实现,它的原型如下。

public StringBuilder Remove(int startIndex,int length) 。从字符串中 startIndex位置处开始移除其后的 count 个的字符

startIndex参数表示移除的开始位置, count参数表示被移除字符串的最大字符串数量。

Page 348: 第 1 章   C# 入门基础

C#从入门到实践

19.3.4 替换字符串

替换字符是指将字符串中指定字符替换为新的字符,或者将指定的字符串替换为新的字符串,该功能由StringBuilder 类的 Replace() 方法实现。

Page 349: 第 1 章   C# 入门基础

C#从入门到实践

19.3.5 复制字符串

复制字符串是指将字符串的内容复制到指定的字符数组中,该功能由 StringBuilder 类的 CopyTo() 方法实现,它的原型如下。

public void CopyTo(int sourceIndex,char[] destination,int destinationIndex,int count) 。

sourceIndex参数指定被复制字符串中的开始位置;destination参数指定将字符复制到的字符数组,用来保存被复制的字符; destinationIndex参数指定保存复制字符的数组中的起始位置; count参数指定被复制字符的数量。

Page 350: 第 1 章   C# 入门基础

C#从入门到实践

19.4 实例一:词频统计

【实例 19-1】使用处理字符串的方法统计给定一段文本中所有单词出现的频率,并按照此频率倒序显示每一个单词的出现的频率。

Page 351: 第 1 章   C# 入门基础

C#从入门到实践

19.5 小结

本章主要介绍了使用 C# 语言处理字符串的方法,如 String类、 StringBuilder 类、不变字符串处理、可变字符串处理等。其中,读者要着重掌握不变字符串处理和可变字符串处理的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 C# 语言中的日期和时间处理。

Page 352: 第 1 章   C# 入门基础

C#从入门到实践

19.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_19” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )在该应用程序分别对静态字符串和动态字符串实现查找、插入、替换、移除指定字符串的功能。

Page 353: 第 1 章   C# 入门基础

C#从入门到实践

第 20 章 日期和时间处理

日期和时间处理是 C# 编程中最为常见的操作之一。在 .NET Framework 中,与日期和时间相关的结构为 DateTime和TimeSpan。 DateTime 结构表示时间上的某一刻, TimeSpan 结构表示时间间隔。本章将讲解 C# 编程中的日期和时间处理,主要介绍以下知识点。

DateTime 结构; TimeSpan 结构;格式化日期和时间; 计算日期和时间差;追加日期和时间。

Page 354: 第 1 章   C# 入门基础

C#从入门到实践

20.1 DateTime 结构

DateTime 是一个结构,且为值类型,表示时间上的一刻,包括日期和时间两部分。 DateTime 表示的值的范围为公元 0001年 1月 1日午夜 12:00:00 到公元 9999年 12月 31日晚上 11:59:59之间的日期和时间。 DateTime 表示的日期和时间由年、月、日、时、分、秒,以及分隔符组成。最常用的一种格式如下所示。

yyyy-MM-dd hh:mm:ss

Page 355: 第 1 章   C# 入门基础

C#从入门到实践

20.1.1 字段

DateTime 结构只包含两个静态只读字段: MaxValue和MinValue ,它们的具体说明如下。

MaxValue字段, DateTime 的最大可能值,它的值为9999年 12月 31日 23:59:59.9999999 。

MinValue字段, DateTime 的最小可能值,它的值为0001年 1月 1日 00:00:00.0000000 。

Page 356: 第 1 章   C# 入门基础

C#从入门到实践

20.1.2 属性

DateTime 结构包含 16 个属性。其中, Now、 Today和UtcNow属性为静态属性,其他属性为实例属性。通过这16 个属性,可以获取时间的值或时间某一个部分的值,如年份、月份、日期、小时、分钟、秒等。

Page 357: 第 1 章   C# 入门基础

C#从入门到实践

20.1.3 方法

DateTime 结构共包括个 38 方法,其中,静态方法 13 个,实例方法 25 个。

Page 358: 第 1 章   C# 入门基础

C#从入门到实践

20.2 TimeSpan 结构

TimeSpan 结构表示一个时间间隔或持续时间,可以按照正负天数、小时数、分钟数、秒数以及秒的小数部分进行度量。

TimeSpan 值表示为“ [-]d.hh:mm:ss.ff”格式的字符串。减号(可选)表示负时间间隔; d分量表示天数; hh 表示小时数( 24 小时制); mm 表示分钟数; ss 表示秒的整数部分, ff 为秒的小数部分。如“ 9.1:40:58” 表示 9天、 1 小时、 40分钟和 58秒。

Page 359: 第 1 章   C# 入门基础

C#从入门到实践

20.2.1 字段

TimeSpan 结构包含以下 8 个静态字段,如MaxValue、MinValue 等,它们的具体说明如下。

MaxValue字段,最大的 TimeSpan 值,它的值为+10675199.02:48:05.4775807 。

MinValue字段,最小的 TimeSpan 值,它的值为 -10675199.02:48:05.4775808 。

Zero字段,零 TimeSpan 值,它的值为 00:00:00 。常常用于与其他 TimeSpan 对象的比较。

TicksPerDay字段,一天中的刻度数,它的值为 8,640亿。 TicksPerHour字段, 1 小时的刻度数,它的值为 360亿。 TicksPerMinute字段, 1分钟的刻度数,它的值为 6亿。 TicksPerSecond字段, 1秒钟的刻度数,它的值为 1,000万

。 TicksPerMillisecond字段, 1毫秒的刻度数,它的值为 1万

Page 360: 第 1 章   C# 入门基础

C#从入门到实践

20.2.2 属性

TimeSpan 结构包含 11 个实例属性。通过这 11 个属性,可以获取TimeSpan 对象的天数、小时数、分钟数、秒数、毫秒数等。 TimeSpan 结构的属性具体说明如表 20.4所示。属性 说明

Days 获取 TimeSpan对象的整天数。

Hours 获取 TimeSpan对象的整小时数。

Minutes 获取 TimeSpan对象的整分钟数。

Seconds 获取 TimeSpan对象的整秒数。

Milliseconds 获取 TimeSpan对象的整毫秒数。

Ticks 获取 TimeSpan对象的刻度数。

TotalDays 获取 TimeSpan对象的天数的整数部分和小数部分。

TotalHours 获取 TimeSpan对象的小时数的整数部分和小数部分。

TotalMinutes 获取 TimeSpan对象的分钟数的整数部分和小数部分。

TotalSeconds 获取 TimeSpan对象的秒数的整数部分和小数部分。

TotalMilliseconds 获取 TimeSpan对象的毫秒数的整数部分和小数部分。

Page 361: 第 1 章   C# 入门基础

C#从入门到实践

20.2.3 方法

TimeSpan 结构共包括个 16 方法,其中,静态方法 10 个,实例方法 6 个。 TimeSpan 结构的静态方法具体说明如表 20.5所示。方法 说明

Compare() 比较两个 TimeSpan值,它的返回值可以是 0、 -1或 1。

Equals() 判断两个 TimeSpan结构的实例是否相等。如果是,则返回 true,否则返回 false。

FromDays() 根据指定的天数,创建一个 TimeSpan结构的实例。

FromHours() 根据指定的小时数,创建一个 TimeSpan结构的实例。

FromMinutes() 根据指定的分钟数,创建一个 TimeSpan结构的实例。

FromSeconds() 根据指定的秒数,创建一个 TimeSpan结构的实例。

FromMilliseconds() 根据指定的毫秒数,创建一个 TimeSpan结构的实例。

FromTicks() 根据指定的刻度数,创建一个 TimeSpan结构的实例。

Parse() 将一个字符串转换为其相应的 TimeSpan对象。

TryParse() 将一个字符串转换为其相应的 TimeSpan对象。

Page 362: 第 1 章   C# 入门基础

C#从入门到实践

20.3 日期和时间的常用操作

DateTime 结构是 C# 编程中最为常用的一个结构之一。日期和时间的常用操作主要包括日期和时间的格式化、计算日期和时间的差、追加日期和时间等。本小节将详细介绍这些操作。

Page 363: 第 1 章   C# 入门基础

C#从入门到实践

20.3.1 格式化

日期和时间格式化是指将 DateTime 结构的实例转换为其相对应的某一种字符串表示形式。 DateTime 结构提供了多个以“ To” 开头的方法。这些方法可以将 DateTime 对象转换为不同格式的字符串形式,常用的方法如表 20.7所示。

方法 说明ToString() 转换为其等效的字符串表示形式。ToLongDateString() 转换为其等效的长日期字符串表示形式。ToShortDateString()

转换为其等效的短日期字符串表示形式。

ToLongTimeString()

转换为其等效的长时间字符串表示形式。

ToShortTimeString()

转换为其等效的短时间字符串表示形式。

Page 364: 第 1 章   C# 入门基础

C#从入门到实践

20.3.2 计算时间差

计算时间差可以使用 Subtract() 方法。该方法可以计算两个时间的差值,也可以计算时间和时间间隔的差值。它存在以下两种重载形式。

public TimeSpan Subtract(DateTime value) ,从当前实例中减去指定的日期和时间,返回类型为 TimeSpan 。其中, value参数表示被减去的日期和时间。

public DateTime Subtract(TimeSpan value) ,从当前实例中减去指定的时间间隔,返回类型为 DateTime 。其中, value参数表示被减去的时间间隔。

Page 365: 第 1 章   C# 入门基础

C#从入门到实践

20.3.3 追加时间

追加时间是指将指定的时间或时间部分(如年份、月份、小时等)追加到一个时间上,并计算出一个新的时间。 DateTime 结构提供多个以“ Add” 开头的方法可以实现追加时间的功能,这些方法的具体说明如表 20.8所示。方法 说明Add() 将指定的 TimeSpan的值加到指定的时间上。AddYears() 将指定的年份数加到指定的时间上。AddMonths() 将指定的月份数加到指定的时间上。AddDays() 将指定的天数加到指定的时间上。AddHours() 将指定的小时数加到指定的时间上。AddMinutes() 将指定的分钟数加到指定的时间上。AddSeconds() 将指定的秒数加到指定的时间上。AddMilliseconds() 将指定的毫秒数加到指定的时间上。

AddTicks() 将指定的刻度数加到指定的时间上。

Page 366: 第 1 章   C# 入门基础

C#从入门到实践

20.4 实例一:计算 for循环的运算时间

【实例 20-1】计算 for循环的运算时间。该功能由ConsumeTime() 方法实现。

Page 367: 第 1 章   C# 入门基础

C#从入门到实践

20.5 小结

本章主要介绍了 C# 语言中的日期和时间处理,如 DateTime结构、 TimeSpan 结构、格式化日期和时间、计算日期和时间差、追加日期和时间等。其中,读者要着重掌握格式化日期和时间,以及计算日期和时间差的方法,为后续编写 C# 程序代码奠定基础。下一章将要介绍 .NET Framework 中的的 IO 流、目录和文件处理。

Page 368: 第 1 章   C# 入门基础

C#从入门到实践

20.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_20” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )获取当前时间,并显示在控制台。( 3 )计算一个 for 语句执行的时间。其中,该 for 语句执行 1000000次。

Page 369: 第 1 章   C# 入门基础

C#从入门到实践

第 21 章 IO 流、目录和文件处理

IO 流、目录和文件处理是系统最为常见的 IO 操作。 IO 流为文件、输入 /输出设备、内部进程通信管道、 TCP/IP套接字提供了操作方法。目录处理包括创建、删除、移动、遍历目录等操作,文件处理包括创建、写入、读取、移动、删除文件等操作。本章将讲解 IO 流、目录和文件处理,主要介绍以下知识点。

文件流; 内存流;目录处理;文件处理。

Page 370: 第 1 章   C# 入门基础

C#从入门到实践

21.1 IO 流

流是字节序列的抽象概念,如文件、输入 /输出设备、内部进程通信管道、 TCP/IP套接字等。 Stream 类是所有流的抽象基类,它可以为流提供一般性视图,从而使得开发人员不需要了解 IO 设备的具体细节。与流相关的操作包括以下 3 个基本操作。

读取流,即读取流中的内容。写入流,即将指定的内容写入到流中。 流支持查找,即可以查找或设置流的当前位置。

Page 371: 第 1 章   C# 入门基础

C#从入门到实践

21.1.1 文件流

FileStream (文件流)类公开以文件为主的 Stream ,它既支持同步读写操作,也支持异步读写操作。使用文件流可以对文件进行读取、写入、打开和关闭操作,以及系统相关操作的标准输入、标准输出等。

FileStream 类包括 9 个属性,它们可以描述 FileStream 类的实例的特性,如流的长度(以字节为单位)、流的当前位置、是否能够读或写或查询等。 FileStream 类的属性的具体说明如表 21.1所示。

Page 372: 第 1 章   C# 入门基础

C#从入门到实践

21.1.2 内存流

MemoryStream 类可以用来创建其支持存储区为内存的流。它可以封装内存中的存储的数据,这些数据的表现形式为无符号字节数组。并且,通过 MemoryStream 类的实例可以直接在内存中访问该数组。特别地,使用内存流可以降低应用程序对临时缓冲区和临时文件的需要。

Page 373: 第 1 章   C# 入门基础

C#从入门到实践

21.2 目录处理

在 .NET Framework 中,用来处理目录的类主要包括Directory和 DirectoryInfo 类。 Directory 类是一个静态类,它公开用于创建、移动、枚举目录和子目录的静态方法。 DirectoryInfo 类是一个密封类,从 FileSystemInfo类派生,并公开用于创建、移动、枚举目录和子目录的实例方法。

Page 374: 第 1 章   C# 入门基础

C#从入门到实践

21.2.1 Directory 类Directory 类是一个静态类,它只包含多个静态方法,用来创建、移动、枚举目录和子目录。其中,常用的静态方法具体说明如表 21.5所示。方法 说明

CreateDirectory() 创建指定路径的目录。

Delete() 删除指定的目录。

Exists() 判断指定路径的目录是否存在。如果存在,返回 true,否则返回 false。

Move() 将指定文件或目录及其内容移到新位置。

GetParent() 获取指定路径的父目录。

GetCurrentDirectory() 获取应用程序的当前工作目录。

SetCurrentDirectory() 设置应用程序的当前工作目录。

GetDirectories() 获取指定目录中子目录。

GetDirectoryRoot() 获取指定路径的卷信息或根信息。

GetFiles() 获取指定目录中的文件。

GetFileSystemEntries() 获取指定目录中所有文件和子目录。

GetLogicalDrives() 获取当前计算机上的逻辑驱动器。

GetCreationTime() 获取目录的创建日期和时间。

SetCreationTime() 设置指定的文件或目录的创建日期和时间。

GetLastAccessTime() 获取上次访问指定文件或目录的日期和时间。

SetLastAccessTime() 设置上次访问指定文件或目录的日期和时间。

GetLastWriteTime() 获取上次写入指定文件或目录的日期和时间。

SetLastWriteTime() 设置上次写入目录的日期和时间。

Page 375: 第 1 章   C# 入门基础

C#从入门到实践

21.2.2 DirectoryInfo 类

DirectoryInfo 类是一个密封类,它可以用来创建、移动、枚举目录和子目录。 DirectoryInfo 类包括 4 个属性,可以用来获取目录的名称、父目录等,具体说明如表 21.6所示。属性 说明

Exists 判断指定目录是否存在。如果存在,则返回 true,否则返回 false。

Name 获取目录的名称。

Parent 获取指定子目录的父目录。

Root 获取路径的根部分。

Page 376: 第 1 章   C# 入门基础

C#从入门到实践

21.2.3 创建目录

创建目录可以使用以下 3 种方法中的任何一种。 Directory 类的 CreateDirectory() 方法,用来创建一个目录。

DirectoryInfo 类的 Create() 方法,用来创建一个目录。 DirectoryInfo 类的 CreateSubdirectory() 方法,用来创建

一个指定目录下的子目录。

Page 377: 第 1 章   C# 入门基础

C#从入门到实践

21.2.4 删除目录

删除目录可以使用以下 2 种方法中的任何一种。 Directory 类的 Delete() 方法,用来删除一个目录。 DirectoryInfo 类的 Delete() 方法,用来删除一个目录。Directory 类的 Delete() 方法存在以下两个原型。 public static void Delete(string path) ,删除 path指定的目录,且该目录必须为空目录。

public static void Delete(string path,bool recursive) ,删除 path指定的目录。 recursive参数指定是否删除该目录下的所有内容(如子目录、文件等)。

Page 378: 第 1 章   C# 入门基础

C#从入门到实践

21.2.5 移动目录

移动目录可以使用以下 2 种方法中的任何一种。 Directory 类的 Move() 方法,将指定文件或目录及其内容

移到新位置。 DirectoryInfo 类的 MoveTo() 方法,将指定目录及其内容

移到新位置。

Page 379: 第 1 章   C# 入门基础

C#从入门到实践

21.2.6 遍历目录

遍历目录是指获取该目录下的子目录或文件,主要存在一下6 种方法。

Directory 类的 GetDirectories() 方法,获取指定目录中子目录。

Directory 类的 GetFiles() 方法,获取指定目录中的文件。 Directory 类的 GetFileSystemEntries() 方法,获取指定目录中所有文件和子目录。

DirectoryInfo 类的 GetDirectories() 方法,获取当前目录的子目录。

DirectoryInfo 类的 GetFiles() 方法,获取当前目录的文件。

DirectoryInfo 类的 GetFileSystemInfos() 方法,获取当前目录的所有文件和子目录。

Page 380: 第 1 章   C# 入门基础

C#从入门到实践

21.3 文件处理

在 .NET Framework 中,用来处理文件的类主要包括 File和FileInfo 类。 File 类是一个静态类,它提供用于创建、复制、删除、移动和打开文件的静态方法。 FileInfo 类是一个密封类,从 FileSystemInfo 类派生,并提供创建、复制、删除、移动和打开文件的实例方法。

Page 381: 第 1 章   C# 入门基础

C#从入门到实践

21.3.1 File 类

File 类是一个静态类,它只包含多个静态方法,用来创建、复制、删除、移动和打开文件。

Page 382: 第 1 章   C# 入门基础

C#从入门到实践

21.3.2 FileInfo 类

FileInfo 类是一个密封类,它可以用来创建、复制、删除、移动和打开文件的实例方法。 FileInfo 类包括 6 个属性,可以用来获取文件的名称、完整路径等,具体说明如表 21.9所示。属性 说明Directory 获取父目录。DirectoryName 获取文件的完整路径。IsReadOnly 获取或设置当前文件是否为只读。Exists 指定当前文件是否存在。Length 获取当前文件的大小(字节)。Name 获取文件的名称。

Page 383: 第 1 章   C# 入门基础

C#从入门到实践

21.3.3 创建文件

创建文件可以使用 File 类的 Create() 方法或者 FileInfo 类的Create() 方法。

【示例 21-18】使用 FileInfo 类的 Create() 方法创建一个名称为“ my.ini” 的文件。

FileInfo fi = new FileInfo("my.ini");

fi.Create();

Page 384: 第 1 章   C# 入门基础

C#从入门到实践

21.3.4 写入文件

存在多种方法,可以将指定内容写入到文件,如 File 类的OpenWrite() 方法、 FileInfo 类的 OpenWrite() 方法等。

Page 385: 第 1 章   C# 入门基础

C#从入门到实践

21.3.5 读取文件

存在多种方法,可以从指定文件中读取内容,如 File 类的OpenRead() 方法、 FileInfo 类的 OpenRead() 方法等。

【示例 21-20】使用 FileInfo 类的 OpenRead() 方法从my.ini文件读取内容,并转换为一个字符串(保存为valuer ),最终,将 valuer 的内容显示在控制台。

Page 386: 第 1 章   C# 入门基础

C#从入门到实践

21.3.6 移动文件

移动文件可以使用以下 2 种方法中的任何一种。 File 类的 Move() 方法,将指定文件移到新位置。 FileInfo 类的 MoveTo() 方法,将指定文件移到新位置。

Page 387: 第 1 章   C# 入门基础

C#从入门到实践

21.3.7 删除文件

删除文件可以使用以下 2 种方法中的任何一种。 File 类的 Delete() 方法,将删除指定的文件。 FileInfo 类的 Delete() 方法,将删除指定的文件。

Page 388: 第 1 章   C# 入门基础

C#从入门到实践

21.4 实例:读取目录下指定类型的文件的内容

【实例 21-1】实现了读取指定目录下的、指定文件类型的、所有文件的内容,并在控制台中显示读取的内容。

Page 389: 第 1 章   C# 入门基础

C#从入门到实践

21.5 小结

本章主要介绍了 .NET Framework 中的 IO 流、目录和文件处理,如文件流、目录流、目录处理、文件处理等。其中,读者要着重掌握目录处理和文件处理,为后续编写对文件操作的 C# 应用程序代码奠定基础。下一章将要介绍C# 语言的 Windows 窗体编程。

Page 390: 第 1 章   C# 入门基础

C#从入门到实践

21.6 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_21” 的控制台应用程序,并实现以下功能。

( 1 )将名称为“ class1.cs” 的文件添加到该应用程序中。( 2 )在 class1.cs文件中是实现使用二进制方法

对“ readme.txt”文件的读写方法。

Page 391: 第 1 章   C# 入门基础

C#从入门到实践

第 22 章 Windows 窗体编程

Windows 窗体应用程序是基于 Microsoft Windows平台至上一种经典的可视化应用程序,它特别适合于包含丰富图形用户界面的应用程序。 Windows 窗体应用程序运行之后,往往会显示一个或多个的 Windows 窗体,具有友好的交互功能。使用 .NET Framework和 C# 语言可以开发功能强大的 Windows 窗体应用程序。本章节主要介绍以下知识点。

Windows 窗体应用程序概述; Windows 窗体基本控件; MainForm.cs 窗体设计; 菜单和工具栏; 容器; 对话框; 数据网格视图控件; 运行 Sample_22 应用程序。

Page 392: 第 1 章   C# 入门基础

C#从入门到实践

22.1 Windows 窗体应用程序概述

本节介绍使用 Microsoft Visual Studio 2008 集成开发环境( IDE )创建 Sample_22 Windows 窗体应用程序的方法,以及该Windows 窗体应用程序的起始点( Program.cs文件)、配置信息( AssemblyInfo.cs文件)等。

Page 393: 第 1 章   C# 入门基础

C#从入门到实践

22.1.1 创建 Sample_22 Windows 窗体应用程序

依次选择“开始” |“所有程序” |“Microsoft Visual Studio 2008”|“Microsoft Visual Studio 2008”命令,打开“起始页 - Microsoft Visual Studio” 窗口。单击“最近项目”面板中的“创建”下的“项目”链接,弹出“新建项目”对话框,如图 22.1所示。

Page 394: 第 1 章   C# 入门基础

C#从入门到实践

22.1.2 应用程序起始点

双击“解决方案资源管理器”面板中的“ Program.cs” 节点,打开 Program.cs文件。该文件为 Sample_22 Windows窗体应用程序提供主入口点。

Page 395: 第 1 章   C# 入门基础

C#从入门到实践

22.1.3 配置程序集信息

首先展开“解决方案资源管理器”面板中的“ Properties”节点,然后双击“ AssemblyInfo.cs” 节点打开AssemblyInfo.cs文件。该文件用来配置 Sample_22 Windows 窗体应用程序的程序集信息。

Page 396: 第 1 章   C# 入门基础

C#从入门到实践

22.2 基本控件

本小节对 Windows 窗体的基本控件做一个简单介绍。这些基本控件包括标签控件、图片框控件、文本框控件、富文本框控件、按钮控件、单项按钮和复选框。

Page 397: 第 1 章   C# 入门基础

C#从入门到实践

22.2.1 标签控件

标签( Label )控件是最为简单的 Windows 窗体控件,它可以用来显示不能编辑的文本或图像。标签控件不能接收焦点,但是可以作为其他控件的访问键。

Page 398: 第 1 章   C# 入门基础

C#从入门到实践

22.2.2 图片框控件

图片框( PictureBox )控件可以用来显示位图、 GIF、 JPEG 、图元文件或图标格式的图形,它显示的图片由 Image属性指定,也可以由 ImageLocation属性指定被显示图片的地址(在显示指定的图片时,由Load() 方法实现)。

Page 399: 第 1 章   C# 入门基础

C#从入门到实践

22.2.3 文本框和富文本框

文本框( TextBox )控件可以用来获取用户输入或显示文本。文本框可以用来编辑文本,也可以以只读方式显示文本。文本框通常显示为单行,但也可以显示多个行。通过Text属性可以获取或设置文本框的输入或显示的文本。

富文本框( RichTextBox )控件和文本框相比,它能够处理有格式的文本,还可以显示字体、颜色、链接、嵌入的图像等。实际上,富文本框能够提供类似字处理应用程序的文本操作和显示功能,如复制、剪切、粘贴、全选等。

Page 400: 第 1 章   C# 入门基础

C#从入门到实践

22.2.4 按钮控件

按钮( Button )控件允许用户通过单击来执行操作。每当用户单击按钮时,即调用该按钮事先定义的 Click事件处理程序。按钮显示的文本可以通过其 Text属性指定,另外,按钮还可以使用 Image 或者 ImageList属性显示图像。

Page 401: 第 1 章   C# 入门基础

C#从入门到实践

22.2.5 单项按钮和复选框

单项按钮由 RadioButton 类实现,可以为用户提供由两个或多个互斥选项组成的选项集。多个单选框可以组合为一个组。对于同一组内的所有单项按钮而言,用户一次只能选中一个单项按钮。复选框由 CheckBox 类实现,它可以用来指定某个条件是打开的还是关闭的,即常常用来提供“是 /否”或者“真 /假”选项。多个复选框也可以组合为一个组,用户可以选择该组中的一个或多个复选框。

Page 402: 第 1 章   C# 入门基础

C#从入门到实践

22.3 MainForm.cs 窗体设计

本小节介绍设计 MainForm.cs 窗体的方法,包括配置窗体的属性(如名称、标题等)、添加控件(如标签控件、按钮控件、图片框控件等)、创建新窗口(如等待对话框等)等方法。

Page 403: 第 1 章   C# 入门基础

C#从入门到实践

22.3.1 配置窗体属性

打开“解决方案资源管理器”面板,并将“ Form1.cs” 节点重命名为“ MainForm.cs” 节点。双击该节点打开MainForm.cs 窗体的设计界面。单击MainForm.cs 窗体,“属性”面板将显示该窗体的各种属性及其值。开发人员还可以通过“属性”面板配置该窗体的各种属性。在此,笔者将 MainForm.cs 窗体的Name属性的值设置为“ MainForm”、 Text属性的值设置为“ Windows 窗体编程”,如图 22.3所示。

Page 404: 第 1 章   C# 入门基础

C#从入门到实践

22.3.2 添加控件

选择“工具箱”中的某一个控件,并直接拖放到MainForm.cs 窗体之上,就可以把该控件添加到MainForm.cs 窗体。在此,笔者向 MainForm.cs 窗体添加了多个控件,并设置了相应的事件。

Page 405: 第 1 章   C# 入门基础

C#从入门到实践

22.3.3 创建等待对话框

下面介绍创建等待对话框(由WaittingForm.cs 窗体实现)的具体步骤。

Page 406: 第 1 章   C# 入门基础

C#从入门到实践

22.3.4 添加窗体事件

打开 MainForm.cs 窗体的设计界面,并双击该窗体就可以为该窗体添加MainForm_Load(object sender, EventArgs e)事件。当系统加载MainForm.cs 窗体时,将触发该事件。

Page 407: 第 1 章   C# 入门基础

C#从入门到实践

22.4 菜单和工具栏

本小节介绍 Windwos 系统中最为熟悉的 3 个控件:菜单(由MenuStrip 类实现)、工具栏(由 ToolStrip 类实现)和上下文菜单(由 ContextMenuStrip 类实现)的使用方法。

Page 408: 第 1 章   C# 入门基础

C#从入门到实践

22.4.1 菜单

菜单由MenuStrip 类实现,它可以通过存放按照一般主题分组的命令将功能公开给用户。使用菜单可以轻松实现以下3 个功能。

创建支持高级用户界面和布局功能的易自定义的常用菜单。

支持操作系统的典型外观和行为。 对所有容器和包含的项进行事件的一致性处理。

Page 409: 第 1 章   C# 入门基础

C#从入门到实践

22.4.2 工具栏

工具栏由 ToolStrip 类型实现,它可以为 Windows 窗体实现工具栏的功能。并且,还可以向工具栏添加按钮、下拉按钮、分割栏、文本框、下拉列表等控件。

Page 410: 第 1 章   C# 入门基础

C#从入门到实践

22.4.3 上下文菜单

上下文菜单由 ContextMenuStrip 类型实现。当用户单击鼠标右键时,将在鼠标位置显示上下文菜单。如果要为某一个窗体添加上下文菜单,只要将上下文菜单( ToolStrip)控件从“工具箱”面板中直接拖放到窗体上即可。

Page 411: 第 1 章   C# 入门基础

C#从入门到实践

22.5 容器

本小节主要介绍 Windwos 系统中最为熟悉的 3 个容器控件:面板(由 Panel 类实现)、组合框(由 GroupBox 类实现)和选项卡(由 TabControl和 TabPage 类实现)的使用方法。

Page 412: 第 1 章   C# 入门基础

C#从入门到实践

22.5.1 面板

面板( Panel )控件是一个容器控件,可以用来包含其他控件,即可以使用面板控件来组合控件的集合。默认情况下,面板控件不显示任何边框。如果要显示边框,则需要设置其 BorderStyle属性的值。特别地,面板控件不显示标题。面板控件包括以下 3 个常用属性。

AutoSizeMode属性,指定控件的自动调整大小行为。 BorderStyle属性,指定控件的边框样式。 TabStop属性,指定用户能否使用 Tab键将焦点放到该

控件上。

Page 413: 第 1 章   C# 入门基础

C#从入门到实践

22.5.2 组合框

组合框( GroupBox )控件和面板控件比较相似,也可以用在其他控件的容器控件。它可以显示围绕一组具有可选标题的控件的框架,并且还可以显示标题。组合框控件最典型的用途是用作一组单项按钮的容器,并指定为以一个逻辑组,组内的单项按钮互相排斥。组合框控件包括以下 8 个常用属性。

AllowDrop属性,指定控件是否允许使用拖放操作和事件。 AutoSize属性,指定控件是否根据其内容调整大小。 AutoSizeMode属性,当控件启用 AutoSize属性时,指定控件的行为

方式。 DisplayRectangle属性,获取控件的维度的矩形。 FlatStyle属性,获取或设置控件的平面样式外观。 TabStop属性,指定用户能否使用 Tab键将焦点放到该控件上。 Text属性,控件的标题。 UseCompatibleTextRendering属性,指定是否使用了兼容文本呈现控

件的标题。

Page 414: 第 1 章   C# 入门基础

C#从入门到实践

22.5.3 TabControl 控件

TabControl 控件可以显示多个选项卡,每一个选项卡都包含一个选项卡页( TabPage )控件,而且每一个选项卡页可以包含其他控件。单击每一个选项卡的标题可以设置它的选项卡页为当前选项卡页。选项卡是 TabControl 控件的一部分,但不是各个选项卡页的一部分。选项卡页控件的属性只影响选项卡页的矩形工作区,而不影响选项卡。 TabControl 控件包括以下 3 个常用属性。

SelectedIndex属性,当前选定的选项卡页的索引。 SelectedTab属性,当前选定的选项卡页。 TabPages属性, TabControl 控件中选项卡页的集合。

Page 415: 第 1 章   C# 入门基础

C#从入门到实践

22.5.4 容器窗体

容器窗体由 ContainForm.cs 窗体实现,介绍了面板、组合框、选项卡等控件的使用方法。该窗体的标题为“容器”,它包括 1个 TabControl 控件、 3个 Tabpage、 1个TextBox 控件、 1个 RichTextBox 控件、 1个 PictureBox、 1个 GroupBox、 3个 RadioButton和 2个 Panel 控件。

Page 416: 第 1 章   C# 入门基础

C#从入门到实践

22.6 对话框

对话框( Dialog )是一种特殊的窗体(其 FormBorderStyle属性的值为 FormBorderStyle.FixedDialog ),常常用于与用户交互和检索信息。本小节介绍 Windows 应用程序最为常用的 5 种对话框:颜色对话框、字体对话框、打开文件对话框、保存文件对话框和目录浏览对话框。

Page 417: 第 1 章   C# 入门基础

C#从入门到实践

22.6.1 对话框窗体

对话框窗体由 DialogForm.cs 窗体实现。用户单击该对话框中的“设置颜色”、“设置字体”、“浏览文件…”、“保存为…”和“浏览目录…”按钮分别弹出颜色对话框、字体对话框、打开文件对话框、保存文件对话框和目录浏览对话框。

Page 418: 第 1 章   C# 入门基础

C#从入门到实践

22.6.2 颜色对话框

颜色对话框由Windows 窗体 ColorDialog 组件实现,它是一个预先设置的对话框。用户可以从该对话框的调色板中选择颜色,以及将自定义颜色添加到该调色板。如果开发基于Windows 的应用程序,开发人员可以使用该对话框来实现选择颜色功能,而不需要再配置自己的对话框。

颜色对话框包括 7 个常用属性,如获取颜色对话框中选择的颜色的 Color属性、禁用“定义自定义颜色”按钮的AllowFullOpen属性等。

Page 419: 第 1 章   C# 入门基础

C#从入门到实践

22.6.3 字体对话框

字体对话框由Windows 窗体 ColorDialog 组件实现,它也是一个预先设置的对话框。用户可以从该对话框中选择系统上当前安装的字体。通过该对话框,用户可以设置文本的字体、样式、大小、脚本和效果。字体对话框包括 5 个常用属性,具体说明如表 22.5所示。

属性 描述

Font 用户选定的字体。

Color 用户选定的字体颜色。

MaxSize 用户可选择的最大磅值。

MinSize 用户可选择的最小磅值。

ShowHelp 指示是否显示“帮助”按钮。

Page 420: 第 1 章   C# 入门基础

C#从入门到实践

22.6.4 打开文件对话框

打开文件对话框由Windows 窗体 OpenFileDialog 组件实现,它与Windows 操作系统所公开的“打开文件”对话框相同。打开文件对话框包括 5 个常用属性,具体说明如表 22.6所示。

属性 描述Multiselect 是否允许选择多个文件。ReadOnlyChecked 是否选定只读复选框。

SafeFileName 所选文件的文件名和扩展名。

SafeFileNames 所有选定文件的文件名和扩展名的数组。

ShowReadOnly 是否包含只读复选框。

Page 421: 第 1 章   C# 入门基础

C#从入门到实践

22.6.5 保存文件对话框

保存文件对话框由Windows 窗体 SaveFileDialog 组件实现,它与Windows 使用的标准“保存文件”对话框相同。保存文件对话框包括 2 个常用属性,具体说明如表 22.7所示。

属性 描述

CreatePrompt 如果用户指定不存在的文件,对话框是否提示用户允许创建该文件。

OverwritePrompt 如果用户指定的文件名已存在,保存文件对话框是否显示警告。

Page 422: 第 1 章   C# 入门基础

C#从入门到实践

22.6.6 目录浏览对话框

目录浏览对话框由Windows 窗体 FolderBrowserDialog 组件实现,它可以显示一个用于浏览和选择文件夹的模式对话框。用户可以从该对话框中选择文件夹。目录浏览对话框包括 4 个常用属性,如获取用户所选择文件夹的路径的 SelectedPath属性、启用“新建文件夹”按钮的 ShowNewFolderButton属性等。这些常用属性的具体说明如表 22.8所示。属性 描述

SelectedPath 用户选定的路径。

ShowNewFolderButton 指示是否显示“新建文件夹”按钮。

Description 对话框中在树视图控件上显示的说明文本。

RootFolder 从其开始浏览的根文件夹。

Page 423: 第 1 章   C# 入门基础

C#从入门到实践

22.7 数据网格视图控件

数据网格视图控件窗体由 DGVForm.cs 窗体实现,该窗体使用 DataGridView (数据网格视图)控件显示数据。 DGVForm.cs 窗体的标题为“数据网格视图控件”,它只包含 1个 DataGridView 控件( Name属性的值为dgvData )。

运行 Sample_22 Windows 窗体应用程序之后,单击“数据网格视图”命令打开“数据网格视图控件”对话框( DGVForm.cs 窗体),如图 22.26所示。

Page 424: 第 1 章   C# 入门基础

C#从入门到实践

22.8 运行应用程序

按下“ F5”按钮或者单击Microsoft Visual Studio 2008 集成开发环境中的按钮即可运行 Sample_22 Windows 窗体应用程序。该应用程序运行之后,显示的第一个窗口为“ Form1” 窗口,如图 22.27所示。

Page 425: 第 1 章   C# 入门基础

C#从入门到实践

22.9 小结

本章主要介绍了 Windows 窗体应用程序,如 Windows 窗体应用程序概述、 Windows 窗体基本控件、 MainForm.cs窗体设计、菜单和工具栏、容器、对话框、数据网格视图控件等。其中,读者要着重掌握Windows 窗体基本控件、菜单、工具栏、容器、对话框和数据网格视图控件的使用方法,为后续编写功能强大的 Windows 应用程序奠定基础。下一章将要介绍 .NET Framework 中的 GDI+绘图技术。

Page 426: 第 1 章   C# 入门基础

C#从入门到实践

22.10 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_22”的Windows 应用程序,并实现等待对话框的功能。

Page 427: 第 1 章   C# 入门基础

C#从入门到实践

第 23 章 使用 GDI+绘图

GDI+是 .NET Framework 中专门用于绘制线条和形状、呈现文本或显示与操作图像的技术。 Graphics 类封装一个GDI+绘图图面, Graphics 对象和点、区域、颜色、刷、画笔、字体等结构或类提供将对象绘制到显示设备的方法。本章节主要介绍以下知识点。

Graphics 类; 点、区域、颜色、刷、画笔和字体;绘制直线、虚线和曲线;绘制多边形和椭圆;绘制饼状图;绘制文本。

Page 428: 第 1 章   C# 入门基础

C#从入门到实践

23.1 GDI+ 概述

GDI+是Windows XP 操作系统中提供二维矢量图形、图像处理和版式的部分。 .NET Framework 为操作图形提供了 GDI+ 应用程序编程接口, GDI+ 是 Windows 图形设备接口( GDI )的高级实现,通过使用 GDI+ ,开发人员可以创建图形、绘制文本,以及以对象的方式来操作图形或图像。

Page 429: 第 1 章   C# 入门基础

C#从入门到实践

23.1.1 Graphics 类

Graphics 类封装一个 GDI+绘图图面,提供将对象绘制到显示设备的方法,是可以用来创建图形图像的对象。通常, Graphics 对象与特定的设备上下文关联。

1 .创建 Graphics 对象2 .绘制图形、文本或图像3 .填充图形或图像

Page 430: 第 1 章   C# 入门基础

C#从入门到实践

23.1.2 点和区域

在 GDI+ 中,二维图像都基于一个二维平面中,并使用点、矩形、区域来描述这些图像。这个二维平面的坐标系如图23.1所示。平面的左上角为坐标系的原点,水平朝右的方向表示 X轴的正方向,垂直朝下的方向表示 Y轴的正方向。

1. Point和 PointF 结构2. Rectangle和 RectangleF 结构3. Size和 SizeF 结构4. Region 类

Page 431: 第 1 章   C# 入门基础

C#从入门到实践

23.1.3 颜色

Color (颜色)结构表示一种 ARGB颜色,它由 4 个分量值( alpha 、红色、绿色和蓝色)组成。 Color 结构包括多个方法,如用来创建颜色的 FromArgb() 方法、 FromKnownColor() 方法、 FromName() 方法等。

Page 432: 第 1 章   C# 入门基础

C#从入门到实践

23.1.4 刷

Brush (刷)类定义用于填充图形形状(如矩形、椭圆、饼形、多边形和封闭路径)的内部的对象。

注意: Brush 类是一个抽象基类,不能进行实例化。若要创建一个刷的实例,必须使用从 Brush 派生出的类,如SolidBrush、 TextureBrush、 LinearGradientBrush 类等。

Page 433: 第 1 章   C# 入门基础

C#从入门到实践

23.1.5 画笔

Pen (画笔)类定义用于绘制直线和曲线的对象,还可以指定直线的宽度、样式等。要创建一个画笔可以使用 Pen类的构造函数。 Pen 类包括 4 个构造函数,具体说明如下。

public Pen(Brush brush) ,使用刷创建画笔。 brush参数指定画笔所使用的刷。

public Pen(Color color) ,使用颜色创建画笔。 color参数指定画笔所使用的颜色。

public Pen(Brush brush,float width) ,使用刷创建画笔。 brush参数指定画笔所使用的刷, width参数指定画笔的宽度。

public Pen(Color color,float width) ,使用颜色创建画笔。 color参数指定画笔所使用的颜色, width参数指定画笔的宽度。

Page 434: 第 1 章   C# 入门基础

C#从入门到实践

23.1.6 字体

Font (字体)类定义特定的文本格式,包括字体、字号和字形属性。创建字体可以使用 Font 类的构造函数。

Page 435: 第 1 章   C# 入门基础

C#从入门到实践

23.2 实例一:使用 GDI+绘制线条、形状和文本

【实例 23-1】使用 GDI+ 中的 Graphics 对象对象在 Panel控件上绘制直线、折线、曲线、虚线、矩形、三角形、多边形、椭圆、饼状图和文本。下面介绍具体实现方法。

Page 436: 第 1 章   C# 入门基础

C#从入门到实践

23.2.1 创建 Sample_23 窗体应用程序

【实例 23-1】创建了名称为“ Sample_23”的Windows Form 应用程序。

Page 437: 第 1 章   C# 入门基础

C#从入门到实践

23.2.2 Paint事件

当重绘 Panel 控件时,会触发 Paint事件。该事件由 Control类(控件的基类)提供, Panel 类继承该事件。在Sample_23 窗体应用程序中,笔者为 pChart 控件添加了Paint事件,并在该事件中为 pChart 控件的顶部绘制了3D边界。该事件的名称为 pChart_Paint(object sender,PaintEventArgs e) 。

Page 438: 第 1 章   C# 入门基础

C#从入门到实践

23.2.3 绘制直线

单击MainForm 窗体中的“绘制直线”按钮可以在 pChart控件中绘制一条直线。该功能由“绘制直线”按钮的Click事件—— btnDrawLine_Click(object sender,EventArgs e) 实现。

Page 439: 第 1 章   C# 入门基础

C#从入门到实践

23.2.4 绘制折线

单击MainForm 窗体中的“绘制折线”按钮可以在 pChart控件中绘制一条折线。该功能由“绘制折线”按钮的Click事件—— btnDrawLines_Click(object sender,EventArgs e) 实现。

Page 440: 第 1 章   C# 入门基础

C#从入门到实践

23.2.5 绘制曲线

单击MainForm 窗体中的“绘制曲线”按钮可以在 pChart控件中绘制一条曲线。该功能由“绘制曲线”按钮的Click事件—— btnDrawCurve_Click(object sender,EventArgs e) 实现。

Page 441: 第 1 章   C# 入门基础

C#从入门到实践

23.2.6 绘制虚线

单击MainForm 窗体中的“绘制虚线”按钮可以在 pChart控件中绘制一条虚线。该功能由“绘制虚线”按钮的Click事件—— btnDrawDashLine_Click(object sender,EventArgs e) 实现。

Page 442: 第 1 章   C# 入门基础

C#从入门到实践

23.2.7 绘制矩形

单击MainForm 窗体中的“绘制矩形”按钮可以在 pChart控件中绘制一个矩形。该功能由“绘制矩形”按钮的Click事件—— btnDrawRect_Click(object sender,EventArgs e) 实现。

Page 443: 第 1 章   C# 入门基础

C#从入门到实践

23.2.8 绘制三角形

单击MainForm 窗体中的“绘制三角形”按钮可以在pChart 控件中绘制一个三角形。该功能由“绘制三角形”按钮的 Click事件—— btnDrawTriangle_Click(object sender,EventArgs e) 实现。

Page 444: 第 1 章   C# 入门基础

C#从入门到实践

23.2.9 绘制多边形

单击MainForm 窗体中的“绘制多边形”按钮可以在pChart 控件中绘制一个多边形。该功能由“绘制多边形”按钮的 Click事件—— btnDrawPolygon_Click(object sender,EventArgs e) 实现。

Page 445: 第 1 章   C# 入门基础

C#从入门到实践

23.2.10 绘制椭圆

单击MainForm 窗体中的“绘制椭圆”按钮可以在 pChart控件中绘制一个椭圆。该功能由“绘制椭圆”按钮的Click事件—— btnDrawEllipse_Click(object sender,EventArgs e) 实现。

Page 446: 第 1 章   C# 入门基础

C#从入门到实践

23.2.11 绘制饼状图

单击MainForm 窗体中的“绘制饼状图”按钮可以在pChart 控件中绘制一个饼状图。该功能由“绘制饼状图”按钮的 Click事件—— btnDrawPie_Click(object sender,EventArgs e) 实现。

Page 447: 第 1 章   C# 入门基础

C#从入门到实践

23.2.12 绘制文本

单击MainForm 窗体中的“绘制文本”按钮可以在 pChart控件中绘制一段文本“这是一段文本。”。该功能由“绘制文本”按钮的 Click事件——btnDrawString_Click(object sender,EventArgs e) 实现。

Page 448: 第 1 章   C# 入门基础

C#从入门到实践

23.3 小结

本章主要介绍了 NET Framework 中的 GDI+绘制技术,如Graphics 类、区域、颜色、刷、画笔、字体等,以及绘制直线、虚线、曲线、多边形、椭圆、饼状图和文本。其中,读者要着重掌握使用 GDI+绘制直线、虚线、曲线、多边形、椭圆、饼状图和文本的方法,为后续编写功能强大的 Windows 应用程序奠定基础。下一章将要介绍 .NET Framework 中的数据访问。

Page 449: 第 1 章   C# 入门基础

C#从入门到实践

23.4 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_23” 的控制台应用程序,并实现以下功能。

( 1 )创建名称为“ MyForm.cs” 的窗体。( 2 )在在名称为“ MyForm.cs” 窗体上绘制以下图形。直线; 折线;曲线; 虚线;矩形; 三角形;多边形; 椭圆;圆; 扇形;饼状图; 文本。

Page 450: 第 1 章   C# 入门基础

C#从入门到实践

第 24 章 .NET数据访问

.NET数据访问是 .NET Framework 中很重要的一个功能,它由 ADO.NET 实现。通过 ADO.NET ,开发人员可以访问Microsoft SQL Server、 ODBC、 Oracle、 OLE DB、 XML 等数据源,并检索、操作和更新这些数据源中的数据。本章节主要介绍以下知识点。

ADO.NET 组成结构; ADO.NET 基本对象,如 SqlCommand、 SqlDataReader、 SqlDataAdpater、 DataSet 等对象;

使用 ADO.NET 操作 SQL Server数据库,包括连接、读取、插入、修改、删除等操作;

使用 DataGridView 控件显示数据; 使用 ListView 控件显示数据; 使用 TreeView 控件显示数据。

Page 451: 第 1 章   C# 入门基础

C#从入门到实践

24.1 ADO.NET 概述

ADO.NET是 .NET Framework 中提供了专门用来处理数据的技术。通过该技术,开发人员可以访问 SQL Server、 ODBC、 Oracle、 OLE DB、 XML 等数据源,并检索、操作和更新这些数据源中的数据。

Page 452: 第 1 章   C# 入门基础

C#从入门到实践

24.1.1 ADO.NET 组成结构

ADO.NET是 .NET Framework 中的一部分,它提供对Microsoft SQL Server、 ODBC、 Oracle 等数据源,以及通过 OLE DB和 XML 公开的数据源的一致访问。应用程序( Windows Form、 ASP.NET 等)可以使用ADO.NET 来连接到这些数据源,并检索、操作和更新其中的数据。 ADO.NET 组成结构如图 24.1所示。

1. .NET Framework数据提供程序2. DataSet (数据集)

DataSet.NET Framework数据提供程序

Connection

事务

Command

参数

DataReader

DataAdapter

SelectCommand

Insertommand

UpdateCommand

DeleteCommand

DataTableCollection

数据表DataRowCollection

DataColumnCollection

ConstraintCollection

DataRelationCollection

数据库

XML

Page 453: 第 1 章   C# 入门基础

C#从入门到实践

24.1.2 ADO.NET 基本对象

ADO.NET 基本对象主要包括Connection、 Command、 DataReader、 DataAdapter、 DataSet、 DataView 等对象。本小节只介绍用于操作SQL Server数据库相关的SqlConnection、 SqlCommand、 SqlDataReader、 SqlDataAdapter、 DataSet、 DataView 等。

1. SqlConnection 对象2. SqlCommand 对象3. SqlDataReader 对象4. DataSet 对象

Page 454: 第 1 章   C# 入门基础

C#从入门到实践

24.2 实例一:操作 SQL Server数据库

【实例 24-1】使用 ADO.NET 实现了操作 SQL Server 2005数据库的功能,包括连接数据库、读取数据、插入数据、修改数据、删除数据、使用 DataGirdView 控件显示数据、使用 ListView 控件显示数据和使用 TreeView 控件显示数据。

Page 455: 第 1 章   C# 入门基础

C#从入门到实践

24.2.1 创建 Sample_24 窗体应用程序

【实例 24-1】创建了名称为“ Sample_24”的Windows Form 应用程序。

Page 456: 第 1 章   C# 入门基础

C#从入门到实践

24.2.2 创建 CSharp3DB数据库

Sample_24 Windows Form 应用程序连接了名称为“ CSharp3DB”的 SQL Server 2005数据库,并操作了该数据库中的数据。

Page 457: 第 1 章   C# 入门基础

C#从入门到实践

24.2.3 连接数据库

单击MainForm 窗体中的“连接数据库”按钮可以连接CSharp3DB数据库。该功能由“连接数据库”按钮的Click事件—— btnConnect_Click(object sender,EventArgs e) 实现。

Page 458: 第 1 章   C# 入门基础

C#从入门到实践

24.2.4 读取数据

单击MainForm 窗体中的“读取数据”按钮可以读取CSharp3DB数据库的 Data 表中的所有数据,并显示在rtbMessage 控件中。该功能由“读取数据”按钮的 Click事件—— btnReadData_Click(object sender,EventArgs e)实现。

Page 459: 第 1 章   C# 入门基础

C#从入门到实践

24.2.5 插入数据

单击MainForm 窗体中的“插入数据”按钮可以向CSharp3DB数据库的 Data 表中插入新的数据。该功能由“插入数据”按钮的 Click事件——btnInsertData_Click(object sender,EventArgs e) 实现。

Page 460: 第 1 章   C# 入门基础

C#从入门到实践

24.2.6 修改数据

单击MainForm 窗体中的“修改数据”按钮可以修改CSharp3DB数据库的 Data 表中的数据。该功能由“修改数据”按钮的 Click事件——btnUpdateData_Click(object sender,EventArgs e) 实现。

Page 461: 第 1 章   C# 入门基础

C#从入门到实践

24.2.7 删除数据

单击MainForm 窗体中的“删除数据”按钮可以删除CSharp3DB数据库的 Data 表中的数据。该功能由“删除数据”按钮的 Click事件—— btnDeleteData_Click(object sender,EventArgs e) 实现。

Page 462: 第 1 章   C# 入门基础

C#从入门到实践

24.2.8 使用 DataGridView 控件显示数据

单击MainForm 窗体中的“显示数据”按钮可以在DataGridView 控件中显示 CSharp3DB数据库的 Data 表中的数据。该功能由 ShowDataWithDataGirdView() 方法实现。

Page 463: 第 1 章   C# 入门基础

C#从入门到实践

24.2.9 使用 ListView 控件显示数据

单击MainForm 窗体中的“显示数据”按钮可以在 ListView控件中显示 CSharp3DB数据库的 Data 表中的数据。该功能由 ShowDataWithListView() 方法实现。

Page 464: 第 1 章   C# 入门基础

C#从入门到实践

24.2.10 使用 TreeView 控件显示数据

单击MainForm 窗体中的“显示”按钮可以在 TreeView 控件中显示 CSharp3DB数据库的 Data 表中的数据。该功能由 ShowDataWithTreeView() 方法实现。

Page 465: 第 1 章   C# 入门基础

C#从入门到实践

24.3 小结

本章主要介绍了 .NET Framework 中中的数据访问功能,如ADO.NET 组成结构、 ADO.NET 基本对象、使用ADO.NET 操作 SQL Server数据库、使用 DataGridView控件显示数据、使用 ListView 控件显示数据、使用TreeView 控件显示数据等。其中,读者要着重掌握ADO.NET 基本对象,以及使用 ADO.NET 操作 SQL Server数据库的方法,为后续编写功能强大的、处理数据(特别是处理数据库中的数据)的 C# 程序代码奠定基础。下一章将要介绍使用 C# 语言开发图书管理系统的方法。

Page 466: 第 1 章   C# 入门基础

C#从入门到实践

24.4 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_24”的Windows 应用程序,并实现以下功能。

( 1 )将名称为“ Form1.cs” 的窗体添加到该应用程序中。( 2 )使用 Form1.cs 窗体实现用户管理功能(包括查询、添加、修改和删除用户)。其中,用户表 User保存在名称为“ UserDB”的 SQL Server 2005数据库中,且该表包含 3 个列: ID、 Username和 Password 。

Page 467: 第 1 章   C# 入门基础

C#从入门到实践

第 25 章 图书管理系统

图书管理系统是当前最为流行的管理系统之一,它一般包括登录、主窗口、图书分类管理、书籍管理、借阅书籍、归还书籍、浏览书籍等功能。本章将讲解使用 Visual Studio 2008 开发图书管理系统(应用程序的名称为“ LibraryManager” ,数据库的名称为“ LibraryManagerDB” ,数据库版本为 SQL Server 2005 )的方法,主要介绍以下知识点。

系统总体设计,包括功能设计、操作流程图、数据库设计等。

管理功能模块实现,包括管理员登录、主窗口、分类管理、书籍管理、借阅书籍等功能。

学生或教师功能模块实现,包括学生或教师登录、主窗口、归还书籍、浏览书籍等功能。

Page 468: 第 1 章   C# 入门基础

C#从入门到实践

25.1 系统总体设计

本小节介绍图书管理系统—— LibraryManager 应用程序的总体设计,主要包括系统功能设计、操作流程图设计、图书管理系统应用程序的组成、 LibraryManagerDB数据库设计、数据库实体类设计、应用程序主入口、应用程序全局变量等。

Page 469: 第 1 章   C# 入门基础

C#从入门到实践

25.1.1 系统功能设计

图书管理系统可以分为两部分:管理员功能模块和学生或老师功能模块。管理员功能模块为管理员提供服务,它提供的功能如下,操作流程如图 25.1所示。

管理员登录 主窗口

删除书籍

查看借阅人

借阅书籍

书籍管理

分类管理

登录

单击【分类管理】图标

单击【添加书籍】按钮/【更新】链接

单击【借阅书籍】按钮

单击借阅数量中的链接

单击【删除】链接

返回

返回

返回

关闭

Page 470: 第 1 章   C# 入门基础

C#从入门到实践

25.1.2 图书管理系统组成

图书管理系统应用程序的名称为“ LibraryManager” 。在 Visual Studio 2008 的“解决方案资源管理器”面板中查看 LibraryManager应用程序,如图 25.3所示。 LibraryManager 应用程序的组成元素说明如下。

Page 471: 第 1 章   C# 入门基础

C#从入门到实践

25.1.3 数据库设计

图书管理系统使用名称为“ LibraryManagerDB”的Microsoft SQL Server 2005数据库,它包括 6 个表:Category、 Group、 User、 Book、 BookCategory和UserBook 表。

1. Category 表2. Group 表3. User 表4. Book 表5. BookCategory 表6. UserBook 表

Page 472: 第 1 章   C# 入门基础

C#从入门到实践

25.1.4 数据库实体类设计

图书管理系统为 LibraryManagerDB数据库创建名称为“ LibraryManagerDB.dbml”的 DBML文件,并把LibraryManagerDB数据库所有的表( Category、 Group、 User、 Book、 BookCategory和 UserBook 表)添加到该文件中,如图 25.4所示。

Page 473: 第 1 章   C# 入门基础

C#从入门到实践

25.1.5 应用程序主入口

应用程序主入口的程序代码位于 Program.cs文件(保存在LibraryManage目录下)中。该文件定义名称为Program 的静态类和 static void Main()静态方法。该静态方法调用 Application 类的 Run()静态方法运行第一个窗口——登录窗体(即 LoginForm 类的实例)

Page 474: 第 1 章   C# 入门基础

C#从入门到实践

25.1.6 应用程序全局变量

图书管理系统在 LibrarySystem.cs文件中创建了LibrarySystem 类,并定义了一个全局的、静态的变量UserID 。该变量用来保存登录用户的 ID 值。

Page 475: 第 1 章   C# 入门基础

C#从入门到实践

25.2 管理员模块实现

管理员功能模块共包括登录、主窗口、分类管理、书籍管理、借阅书籍、查看借阅人等功能。管理员都能够通过主窗口查看和浏览所有书籍,以及书籍的借阅情况;借阅书籍窗口可以实现借阅书籍的功能,查看借阅人窗口可以查看某一个书籍的所有借阅人的信息。本小节介绍这些功能模块木咛迨迪帧

Page 476: 第 1 章   C# 入门基础

C#从入门到实践

25.2.1 管理员登录

管理员登录功能由 LoginForm.cs 窗体(保存在LibraryManager目录下)实现。管理员可以输入用户名和密码,单击“登录”按钮实现登录功能,单击“取消”按钮关闭该窗口。

Page 477: 第 1 章   C# 入门基础

C#从入门到实践

25.2.2 主窗口

管理员主窗口由MainForm.cs 窗体(保存在LibraryManager目录下)实现。该窗口以列表形式显示指定分类下的书籍;管理员单击“分类管理”图标打开分类管理的窗口,单击“添加新书籍”按钮可以打开书籍管理窗口,单击“借阅书籍”按钮打开借阅书籍的窗口。

Page 478: 第 1 章   C# 入门基础

C#从入门到实践

25.2.3 分类管理

分类管理功能由CategoryForm.cs 窗体(保存在 LibraryManager/Admin目录下)实现。管理员可以创建和维护书籍的分类树,如添加新的分类、修改分类名称、删除分类等。

Page 479: 第 1 章   C# 入门基础

C#从入门到实践

25.2.4 书籍管理

书籍管理功能由 BookForm.cs 窗体(保存在LibraryManager/Admin目录下)实现。管理员可以输入用户名和密码,单击“登录”按钮实现登录功能,单击“取消”按钮关闭该窗口。

Page 480: 第 1 章   C# 入门基础

C#从入门到实践

25.2.5 借阅书籍

借阅书籍功能由 LendForm.cs 窗体(保存在LibraryManager目录下)实现。该窗体实现借阅指定书籍给指定用户的功能。管理员可以选择借阅书籍的用户。

Page 481: 第 1 章   C# 入门基础

C#从入门到实践

25.2.6 查看借阅人

查看借阅人功能由 LendUserInfoForm.cs 窗体(保存在LibraryManager目录下)实现。该窗口可以以列表方式显示指定书籍的所有借阅人的信息。

Page 482: 第 1 章   C# 入门基础

C#从入门到实践

25.3 学生和老师功能模块实现

学生和老师功能模块共包括登录、主窗口、归还书籍、查看书籍信息、浏览书籍、借阅书籍等功能。学生和老师都能够通过主窗口查看其所借阅的书籍,并能够归还书籍;浏览书籍窗口可以根据书籍分类浏览各种书籍,并借阅书籍。本小节介绍这些功能模块的具体实现。

Page 483: 第 1 章   C# 入门基础

C#从入门到实践

25.3.1 学生或老师登录

学生或老师登录功能也是由 LoginForm.cs 窗体(保存在LibraryManager目录下)实现。学生或老师也可以输入用户名和密码,单击“登录”按钮实现登录功能,单击“取消”按钮关闭该窗口。由于已经在 25.2.1 小节介绍了该窗体的实现,因此,在此不做详细介绍。

Page 484: 第 1 章   C# 入门基础

C#从入门到实践

25.3.2 主窗口

学生和老师角色的主窗口都为由 UserForm.cs 窗体(保存在LibraryManager目录下)实现。该窗口以列表形式显示学生或老师已借的所有书籍;学生或老师单击“归还书籍”按钮可以归还选择的书籍;单击“浏览书籍”按钮可以打开浏览书籍的窗口。

Page 485: 第 1 章   C# 入门基础

C#从入门到实践

25.3.3 归还书籍

当用户单击 UserForm.cs 窗体中的“归还书籍”按钮( btnReturn 控件)触发 Click事件——btnReturn_Click(object sender, EventArgs e) 。该事件实现归还书籍的功能。

Page 486: 第 1 章   C# 入门基础

C#从入门到实践

25.3.4 查看书籍信息

查看书籍信息功能由BookInfoForm.cs 窗体(保存在 LibraryManager目录下)实现。该窗口可以显示指定书籍的详细信息,如名称、作者、 ISBN 、出版单位、出版时间、数量、状态、电子文档、封面图片、图书简介、图书分类等。

Page 487: 第 1 章   C# 入门基础

C#从入门到实践

25.3.5 浏览书籍

浏览书籍功能由 BrowserForm.cs 窗体(保存在LibraryManager目录下)实现。该窗口根据分类、以列表形式显示书籍信息,单击“借阅”链接可以借阅当前行表示的书籍。

Page 488: 第 1 章   C# 入门基础

C#从入门到实践

25.3.6 借阅书籍

当用户单击“浏览书籍”窗口( BrowserForm.cs 窗体)中每一行中的“借阅”链接时,可以实现借阅该行表示的书籍。该功能的实现方式和 25.2.5 小节中借阅书籍功能相似,因此,在此不做详细介绍。

Page 489: 第 1 章   C# 入门基础

C#从入门到实践

25.4 小结

本章主要介绍了使用 C# 语言在 Visual Studio 2008 集成开发环境中开发图书管理系统的方法,主要包括功能设计、操作流程图、数据库设计,以及管理员登录、主窗口、分类管理、书籍管理、借阅书籍、学生或教师登录、主窗口、归还书籍、浏览书籍等功能的开发方法。其中,读者要着重掌握使用 Windows 窗体编程的方法,为后续编功能强大的 Windows 应用程序奠定基础。下一章将要介绍 P2P(点对点)聊天程序。

Page 490: 第 1 章   C# 入门基础

C#从入门到实践

25.5 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_25”的Windows 应用程序,并在该应用程序中实现用户管理功能。

Page 491: 第 1 章   C# 入门基础

C#从入门到实践

第 26 章 P2P聊天工具

P2P聊天工具是当前最为流行的点对点的聊天工具,它一般包括聊天工具的服务器、聊天工具的客户端等功能模块。本章将讲解使用 Visual Studio 2008 集成开发环境开发P2P聊天工具(名称为“ P2PTalk” )的方法,主要介绍以下知识点。

系统总体设计,包括功能设计、 P2P聊天工具组成等; P2P聊天工具类库实现; P2P聊天工具服务器聊天窗口实现; P2P聊天工具客户端聊天窗体实现。

Page 492: 第 1 章   C# 入门基础

C#从入门到实践

26.1 系统总体设计

本小节介绍 P2P聊天工具—— P2PTalk项目的总体设计,主要包括系统功能设计、 P2P聊天工具的组成等。

Page 493: 第 1 章   C# 入门基础

C#从入门到实践

26.1.1 系统功能设计

P2P聊天工具可以分为两部分: P2P聊天工具客户端部分功能模块和 P2P聊天工具服务器端部分功能模块。 P2P聊天工具的客户端部分和服务器端部分功能模块都实现相同的功能,具体描述如下。

连接服务器,连接到指定的聊天服务器。断开服务器的连接,断开已经连接的聊天服务器。退出聊天,退出聊天状态,并释放占有的资源。 发送聊天消息,可以将消息发送到服务器。

Page 494: 第 1 章   C# 入门基础

C#从入门到实践

26.1.2 P2P聊天工具组成

P2P聊天工具项目的名称为“ P2PTalk” 。在 Visual Studio 2008 的“解决方案资源管理器”面板中查看 P2PTalk项目,如图 26.1所示。 P2PTalk项目包括 3 个应用程序,具体说明如下。

Client 应用程序, P2P聊天工具的客户端应用程序。 P2PTalkLibrary 类库, P2P聊天工具的类库,封装了实

现聊天功能的类。 Server 应用程序, P2P聊天工具的服务器端应用程序。

Page 495: 第 1 章   C# 入门基础

C#从入门到实践

26.2 P2P聊天工具类库实现

P2P聊天工具类库由 P2PTalkLibrary项目实现,该项目的类型为 C# 类库。如果生成该项目成功,将创建一个名称为“ P2PTalkLibrary.dll” 的动态链接库文件(保存在该项目的 bin目录下)。

P2PTalkLibrary项目包括两个类文件: P2P.cs和 Tool.cs ,它们分别包含 P2P 类和 Tool 类。下面将详细介绍这两个类的功能。

Page 496: 第 1 章   C# 入门基础

C#从入门到实践

26.2.1 Tool 类

Tool 类被包含在 P2PTalk.Component命名空间中,并引用了 2 个命名空间: System.Net和 System.IO 。

Page 497: 第 1 章   C# 入门基础

C#从入门到实践

26.2.2 P2P 类

P2P 类被包含在 P2PTalk.Component命名空间中,并引用了 2 个命名空间: System.Net和 System.IO 。

Page 498: 第 1 章   C# 入门基础

C#从入门到实践

26.3 P2P聊天工具服务器聊天窗口

P2P聊天工具服务器由 Server项目实现, P2P聊天工具服务器聊天窗口由该项目下的 MainForm.cs 窗体(保存在P2PTalk目录下)实现。用户可以通过该窗口连接服务器,并和其他用户进行聊天。用户单击“连接”按钮可以连接到指定的服务器,单击“断开”按钮可以断开服务器的连接,单击“退出”按钮可以结束当前聊天状态,单击“发送”按钮可以将详细发送给其他在线用户。

Page 499: 第 1 章   C# 入门基础

C#从入门到实践

26.4 P2P聊天工具客户端聊天窗口

由于 P2P聊天工具客户端聊天窗口和 P2P聊天工具服务器聊天窗口功能上非常相似,实现方法也比较相似。因此,在此不做详细介绍。

Page 500: 第 1 章   C# 入门基础

C#从入门到实践

26.5 小结

本章主要介绍了使用 C# 语言在 Visual Studio 2008 集成开发环境中开发 P2P聊天工具的方法,主要包括功能设计、 P2P聊天工具组成,以及 P2P聊天工具类库、 P2P聊天工具服务器聊天窗口、 P2P聊天工具客户端聊天窗体等功能的开发方法。其中,读者要着重掌握 P2P聊天工具类库和 P2P聊天工具客户端聊天窗体的方法,为后续编功能强大的网络应用程序奠定基础。下一章将要介绍使用 ASP.NET 技术( C# )开发校内网的方法。

Page 501: 第 1 章   C# 入门基础

C#从入门到实践

26.6 习题

在 Server 应用程序( 26.3 小节)中添加用户管理功能,并实现可以将指定的消息仅仅发送的指定的某一个用户个功能。

Page 502: 第 1 章   C# 入门基础

C#从入门到实践

第 27 章 我的校内网

校内网是当前最为流行的交流网站之一,它一般包括登录、主页面、好友、相册、日志、聊天等功能。本章将讲解使用 Visual Studio 2008 集成开发环境开发校内网网站(名称为“ MyXiaonei” ,数据库的名称为“ XiaoneiDB” ,数据库版本为 SQL Server 2005 )的方法,主要介绍以下知识点。

系统总体设计,包括功能设计、数据库设计等。 常用功能模块实现,包括登录、主页面、好友、相册、日志等功能。

Page 503: 第 1 章   C# 入门基础

C#从入门到实践

27.1 系统总体设计

本小节介绍校内网—— MyXiaonei 网站的总体设计,主要包括系统功能设计、 MyXiaonei 网站的组成、 XiaoneiDB数据库设计、数据库实体类设计、标题模块、网站配置等。

Page 504: 第 1 章   C# 入门基础

C#从入门到实践

27.1.1 系统功能设计

校内网网站比较复杂,在此,仅仅介绍常用的功能,主要包括登录、好友(浏览好友、添加好友等)、相册(浏览照片、上传照片等)、日志等功能,具体描述如下。

用户登录,验证用户的身份是否合法。 主页面,校内网网站的主页面。我的好友,按照分类方式浏览好友。添加好友,可以查询用户,并添加为好友。我的相册,按照分类方式浏览照片。 上传照片,上传照片到服务器,并指定相应的分类。我的日志,按照分类方式浏览日志。添加日志,将新的日志添加到指定的分类下。

Page 505: 第 1 章   C# 入门基础

C#从入门到实践

27.1.2 校内网组成

校内网网站的名称为“ MyXiaonei” 。在 Visual Studio 2008的“解决方案资源管理器”面板中查看MyXiaonei 网站,如图 27.1所示。

Page 506: 第 1 章   C# 入门基础

C#从入门到实践

27.1.3 数据库设计

校内网网站使用名称为“ XiaoneiDB”的Microsoft SQL Server 2005数据库,它包括 6 个表: Category、 Group、 User、 Book、 BookCategory和 UserBook 表。

1. User 表2. Category 表3. Friend 表4. Log 表5. Photo 表

Page 507: 第 1 章   C# 入门基础

C#从入门到实践

27.1.4 数据库实体类设计

校内网网站为 XiaoneiDB数据库创建名称为“ XiaoneiDB.dbml”的 DBML文件,并把 XiaoneiDB数据库所有的表( User、 Category、 Friend、 Log和Photo 表)添加到该文件中,如图 27.2所示。

Page 508: 第 1 章   C# 入门基础

C#从入门到实践

27.1.5 标题模块

标题模块由 TitleUC.ascx 用户控件实现,它将用来显示标题。

Page 509: 第 1 章   C# 入门基础

C#从入门到实践

27.1.6 配置文件 Web.config

MyXiaonei 网站的连接字符串放置在 Web.config 配置文件的 <connectionString>元素中

Page 510: 第 1 章   C# 入门基础

C#从入门到实践

27.2 常用功能模块实现

校内网网站的常用功能模块主要包括登录、好友(浏览好友、添加好友等)、相册(浏览照片、上传照片等)、日志等功能。本小节将介绍这些功能的具体实现方法。

Page 511: 第 1 章   C# 入门基础

C#从入门到实践

27.2.1 登录页面

登录功能由 Default.aspx页面实现, Default.aspx.cs文件为它的代码隐藏文件。该页面提供了输入用户名和密码的文本框,并实现用户登录的功能。 Default.aspx页面的效果图如图 27.3所示。

1 .界面设计2 .事件设计

Page 512: 第 1 章   C# 入门基础

C#从入门到实践

27.2.2 主页面

校内网主页面由Main.aspx和 LeftTree.aspx页面共同实现。Main.aspx页面使用了框架,并放置了两个 <frame>元素,它们的 name属性的值分别为: Left和 Desktop 。其中, Left 框架放置 LeftTree.aspx页面, Desktop 框架默认放置 MyFriend.aspx页面。

Page 513: 第 1 章   C# 入门基础

C#从入门到实践

27.2.3 我的好友

我的好友由MyFriend.aspx页面实现, MyFriend.aspx.cs文件为它的代码隐藏文件。该页面按照系统默认的分类显示当前登录用户的好友。 MyFriend.aspx页面的效果图如图27.4所示。

1 .界面设计2 .初始化3 .事件设计

Page 514: 第 1 章   C# 入门基础

C#从入门到实践

27.2.4 添加好友

添加好友由 AddFriend.aspx页面实现, AddFriend.aspx.cs文件为它的代码隐藏文件。该页面为考生提供选择考试科目的功能,并显示用户名称和考试时间。 AddFriend.aspx页面的效果图如图 27.5所示。

1 .界面设计2 .初始化3 .事件设计

Page 515: 第 1 章   C# 入门基础

C#从入门到实践

27.2.5 我的相册

我的相册由MyPhoto.aspx页面实现, MyPhoto.aspx.cs文件为它的代码隐藏文件。该页面按照系统默认的分类显示当前登录用户的照片。 MyPhoto.aspx页面的效果图如图27.6所示。

1 .界面设计2 .初始化3 .事件设计

Page 516: 第 1 章   C# 入门基础

C#从入门到实践

27.2.6 上传照片

上传照片由 UploadPhoto.aspx页面实现, UploadPhoto.aspx.cs文件为它的代码隐藏文件。该页面为用户提供上传照片的功能。其中,照片的文件保存到硬盘,照片的信息保存到数据库。 UploadPhoto.aspx页面的效果图如图 27.7所示。

1 .界面设计2 .初始化3 .事件设计

Page 517: 第 1 章   C# 入门基础

C#从入门到实践

27.2.7 我的日志

我的日志由MyLog.aspx页面实现, MyLog.aspx.cs文件为它的代码隐藏文件。该页面按照系统默认的分类显示当前登录用户的日志。 MyLog.aspx页面的效果图如图 27.8所示。

1 .界面设计2 .初始化3 .事件设计

Page 518: 第 1 章   C# 入门基础

C#从入门到实践

27.2.8 添加日志

添加日志由 AddLog.aspx页面实现, AddLog.aspx.cs文件为它的代码隐藏文件。该页面为考生提供输入日志标题和内容,并提交到数据库的功能。 AddLog.aspx页面的效果图如图 27.9所示。

1 .界面设计2 .初始化3 .事件设计

Page 519: 第 1 章   C# 入门基础

C#从入门到实践

27.3 小结

本章主要介绍了使用 C# 语言在 Visual Studio 2008 集成开发环境中开发校内网的方法,主要包括统总体设计,包括功能设计、数据库设计,以及登录、主页面、好友、相册、日志、聊天等功能的开发方法。其中,读者要着重掌握使用Web 窗体编程的方法,为后续编功能强大的 ASP.NET网站奠定基础。

Page 520: 第 1 章   C# 入门基础

C#从入门到实践

27.4 习题

在 Visual Studio 2008 集成开发环境中创建名称为“ Test_27”的 ASP.NET 网站,并在该网站中实现用户管理功能。

Page 521: 第 1 章   C# 入门基础

C#从入门到实践