1、C#基础教程第一章 C#语言基础本章介绍 C#语言的基础知识,希望具有 C 语言的读者能够基本掌握 C#语言,并以此为基础,能够进一步学习用 C#语言编写 window 应用程序和 Web 应用程序。当然仅靠一章的内容就完全掌握 C#语言是不可能的,如需进一步学习 C#语言,还需要认真阅读有关 C#语言的专著。1.1 C#语言特点Microsoft.NET(以下简称.NET)框架是微软提出的新一代 Web 软件开发模型,C#语言是.NET 框架中新一代的开发工具。C#语言是一种现代、面向对象的语言,它简化了 C+语言在类、命名空间、方法重载和异常处理等方面的操作,它摒弃了 C+的复杂性,更易使
2、用,更少出错。它使用组件编程,和VB 一样容易使用。C#语法和 C+和 JAVA 语法非常相似,如果读者用过 C+和 JAVA,学习 C#语言应是比较轻松的。用 C#语言编写的源程序,必须用 C#语言编译器将 C#源程序编译为中间语言(MicroSoft Intermediate Language,MSIL)代码,形成扩展名为 exe 或 dll 文件。中间语言代码不是 CPU 可执行的机器码,在程序运行时,必须由通用语言运行环境(Common Language Runtime,CLR)中的既时编译器(JUST IN Time,JIT)将中间语言代码翻译为 CPU 可执行的机器码,由 CPU
3、执行。CLR 为 C#语言中间语言代码运行提供了一种运行时环境,C#语言的 CLR 和 JAVA 语言的虚拟机类似。这种执行方法使运行速度变慢,但带来其它一些好处,主要有:l 通用语言规范 (Common Language Specification,CLS) :.NET 系统包括如下语言:C#、C+、VB、J#,他们都遵守通用语言规范。任何遵守通用语言规范的语言源程序,都可编译为相同的中间语言代码,由 CLR 负责执行。只要为其它操作系统编制相应的 CLR,中间语言代码也可在其它系统中运行。l 自动内存管理:CLR 内建垃圾收集器,当变量实例的生命周期结束时,垃圾收集器负责收回不被使用的实例
4、占用的内存空间。不必象 C 和 C+语言,用语句在堆中建立的实例,必须用语句释放实例占用的内存空间。也就是说,CLR 具有自动内存管理功能。l 交叉语言处理:由于任何遵守通用语言规范的语言源程序,都可编译为相同的中间语言代码,不同语言设计的组件,可以互相通用,可以从其它语言定义的类派生出本语言的新类。由于中间语言代码由 CLR负责执行,因此异常处理方法是一致的,这在调试一种语言调用另一种语言的子程序时,显得特别方便。l 增加安全:C# 语言不支持指针,一切对内存的访问都必须通过对象的引用变量来实现,只允许访问内存中允许访问的部分,这就防止病毒程序使用非法指针访问私有成员。也避免指针的误操作产生
5、的错误。CLR 执行中间语言代码前,要对中间语言代码的安全性,完整性进行验证,防止病毒对中间语言代码的修改。l 版本支持:系统中的组件或动态联接库可能要升级,由于这些组件或动态联接库都要在注册表中注册,由此可能带来一系列问题,例如,安装新程序时自动安装新组件替换旧组件,有可能使某些必须使用旧组件才可以运行的程序,使用新组件运行不了。在.NET 中这些组件或动态联接库不必在注册表中注册,每个程序都可以使用自带的组件或动态联接库,只要把这些组件或动态联接库放到运行程序所在文件夹的子文件夹 bin 中,运行程序就自动使用在 bin 文件夹中的组件或动态联接库。由于不需要在注册表中注册,软件的安装也变
6、得容易了,一般将运行程序及库文件拷贝到指定文件夹中就可以了。l 完全面向对象:不象 C+语言,即支持面向过程程序设计,又支持面向对象程序设计,C#语言是完全面向对象的,在 C#中不再存在全局函数、全局变量,所有的函数、变量和常量都必须定义在类中,避免了命名冲突。C#语言不支持多重继承。1.2 编写控制台应用程序使用 SDK 命令行工具编写控制台程序第一个程序总是非常简单的,程序首先让用户通过键盘输入自己的名字,然后程序在屏幕上打印一条欢迎信息。程序的代码是这样的:using System;/导入命名空间。/为 C#语言新增解释方法,解释到本行结束class Welcome/类定义,类的概念见下
7、一节 /*解释开始,和 C 语言解释用法相同解释结束*/static void Main()/主程序,程序入口函数,必须在一个类中定义 Console.WriteLine(“请键入你的姓名:“);/ 控制台输出字符串Console.ReadLine();/从键盘读入数据,输入回车结束Console.WriteLine(“欢迎!“);可以用任意一种文本编辑软件完成上述代码的编写,然后把文件存盘,假设文件名叫做welcome.cs,C#源文件是以 cs 作为文件的扩展名。和 C 语言相同,C#语言是区分大小写的。高级语言总是依赖于许多在程序外部预定义的变量和函数。在 C 或 C+中这些定义一般放到
8、头文件中,用#include 语句来导入这个头文件。而在 C#语言中使用 using 语句导入名字空间,using System 语句意义是导入 System 名字空间,C#中的using 语句的用途与 C+中#include 语句的用途基本类似,用于导入预定义的变量和函数,这样在自己的程序中就可以自由地使用这些变量和函数。如果没有导入名字空间的话我们该怎么办呢?程序还能保持正确吗?答案是肯定的,那样的话我们就必须把代码改写成下面的样子:class Welcome static void Main() System.Console.WriteLine(“请键入你的姓名:“);System.Co
9、nsole.ReadLine();System.Console.WriteLine(“欢迎!“);也就是在每个 Console 前加上一个前缀 System.,这个小原点表示 Console 是作为 System 的成员而存在的。C#中抛弃了 C 和 C+中繁杂且极易出错的操作符象:和-等,C#中的复合名字一律通过.来连接。System 是.Net 平台框架提供的最基本的名字空间之一,有关名字空间的详细使用方法将在以后详细介绍,这里只要学会怎样导入名字空间就足够了。程序的第二行 class Welcome 声明了一个类,类的名字叫做 Welcome。C#程序中每个变量或函数都必须属于一个类,包
10、括主函数 Main(),不能象 C 或 C+那样建立全局变量。 C#语言程序总是从Main()方法开始执行,一个程序中不允许出现两个或两个以上的 Main()方法。请牢记 C#中 Main()方法必须被包含在一个类中,Main 第一个字母必须大写,必须是一个静态方法,也就是 Main()方法必须使用 static修饰。static void Main()是类 Welcome 中定义的主函数。静态方法意义见以后章节。程序所完成的输入输出功能是通过 Console 类来完成的,Console 是在名字空间 System 中已经定义好的一个类。Console 类有两个最基本的方法 WriteLine
11、 和 ReadLine。ReadLine 表示从输入设备输入数据,WriteLine 则用于在输出设备上输出数据。如果在电脑上安装了 Visual Studio.Net,则可以在集成开发环境中直接选择快捷键或菜单命令编译并执行源文件。如果您不具备这个条件,那么至少需要安装 Microsoft.Net Framework SDK,这样才能够运行C#语言程序。Microsoft.Net Framework SDK 中内置了 C#的编译器 csc.exe,下面让我们使用这个微软提供的命令行编译器对程序 welcome.cs 进行编译。假设已经将 welcome.cs 文件保存在d:Charp 目录下
12、,启动命令行提示符,在屏幕上输入一行命令:d: 回车,cd Charp 回车,键入命令:C:WINNTMicrosoft.NETFrameworkv1.0.3705csc welcome.cs如果一切正常 welcome.cs 文件将被编译,编译后生成可执行文件 Welcome.exe。可以在命令提示符窗口运行可执行文件 Welcome.exe,屏幕上出现一行字符提示您输入姓名:请键入你的姓名:输入任意字符并按下回车键,屏幕将打印出欢迎信息:欢迎!注意,和我们使用过的绝大多数编译器不同,在 C#中编译器只执行编译这个过程,而在C 和 C+中要经过编译和链接两个阶段。换而言之 C#源文件并不被编
13、译为目标文件.obj ,而是直接生成可执行文件.exe 或动态链接库.dll,C#编译器中不需要包含链接器。使用 Visual Studio.Net 建立控制台程序(1) 运行 Visual Studio.Net 程序,出现如图 1.2.2A 界面。(2) 单击新建项目按钮,出现如图 1.2.2B 对话框。在项目类型 (P)编辑框中选择 Visual C#项目,在模板(T)编辑框中选择控制台应用程序,在名称(N)编辑框中键入 e1,在位置(L) 编辑框中键入D:csarp,必须预先创建文件夹 D:csarp。也可以单击浏览按钮,在打开文件对话框中选择文件夹。单击确定按钮,创建项目。出现如图 1
14、.2.2C 界面。编写一个应用程序,可能包含多个文件,才能生成可执行文件,所有这些文件的集合叫做一个项目。(3) 修改 class1.cs 文件如下,有阴影部分是新增加的语句,其余是集成环境自动生成的。using System;namespace e1/ / Class1 的摘要说明。/ class Class1/ / 应用程序的主入口点。/ STAThreadstatic void Main(string args)/ TODO: 在此处添加代码以启动应用程序/Console.WriteLine(“请键入你的姓名:“);Console.ReadLine();Console.WriteLine
15、(“欢迎!“);(4) 按 CTRL+F5 键,运行程序,如右图,和 1.2.1 节运行效果相同。屏幕上出现一行字符,提示您输入姓名:请键入你的姓名:输入任意字符并按下回车键,屏幕将打印出欢迎信息:欢迎!输入回车退出程序。图 1.2.2A图 1.2.2B1.3 类的基本概念C#语言是一种现代、面向对象的语言。面向对象程序设计方法提出了一个全新的概念:类,它的主要思想是将数据(数据成员)及处理这些数据的相应方法(函数成员)封装到类中,类的实例则称为对象。这就是我们常说的封装性。类的基本概念类可以认为是对结构的扩充,它和 C 中的结构最大的不同是:类中不但可以包括数据,还包括处理这些数据的函数。类
16、是对数据和处理数据的方法(函数)的封装。类是对某一类具有相同特性和行为的事物的描述。例如,定义一个描述个人情况的类 Person 如下:using System;class Person/类的定义, class 是保留字,表示定义一个类,Person 是类名 private string name=“张三“;/ 类的数据成员声明private int age=12;/private 表示私有数据成员public void Display()/类的方法(函数) 声明,显示姓名和年龄 Console.WriteLine(“姓名:0, 年龄:1“,name,age);public void SetN
17、ame(string PersonName)/修改姓名的方法(函数) name=PersonName;public void SetAge(int PersonAge) age=PersonAge;Console.WriteLine(“姓名:0,年龄:1“,name,age) 的意义是将第二个参数变量 name 变为字符串填到0位置,将第三个参数变量 age 变为字符串填到1位置,将第一个参数表示的字符串在显示器上输出。大家注意,这里我们实际定义了一个新的数据类型,为用户自己定义的数据类型,是对个人的特性和行为的描述,他的类型名为 Person,和 int,char 等一样为一种数据类型。用定
18、义新数据类型Person 类的方法把数据和处理数据的函数封装起来。类的声明格式如下:属性 类修饰符 class 类名 类体其中,关键字 class、类名和类体是必须的,其它项是可选项。类修饰符包括new、public、protected、internal、private、abstract 和 sealed,这些类修饰符以后介绍。类体用于定义类的成员。1.3.2 类成员的存取控制一般希望类中一些数据不被随意修改,只能按指定方法修改,既隐蔽一些数据。同样一些函数也不希望被其它类程序调用,只能在类内部使用。如何解决这个问题呢?可用访问权限控制字,常用的访问权限控制字如下:private( 私有) ,
19、 public(公有)。在数据成员或函数成员前增加访问权限控制字,可以指定该数据成员或函数成员的访问权限。私有数据成员只能被类内部的函数使用和修改,私有函数成员只能被类内部的其它函数调用。类的公有函数成员可以被类的外部程序调用,类的公有数据成员可以被类的外部程序直接使用修改。公有函数实际是一个类和外部通讯的接口,外部函数通过调用公有函数,按照预先设定好的方法修改类的私有成员。对于上述例子,name 和 age 是私有数据成员,只能通过公有函数 SetName()和 SetAge()修改,既它们只能按指定方法修改。这里再一次解释一下封装,它有两个意义,第一是把数据和处理数据的方法同时定义在类中。第二是用访问权限控制字使数据隐蔽。1.3.3 类的对象Person 类仅是一个用户新定义的数据类型,由它可以生成 Person 类的实例,C# 语言叫对象。用如下方法声明类的对象:Person OnePerson=new Person();此语句的意义是建立 Person 类对象,返回对象地址赋值给 Person 类变量 OnePerson。也可以分两步创建 Person 类的对象:Person OnePerson;OnePerson=new Person();OnePerson 虽然存储的是 Person 类对象地址,但不是 C 中的指针,不能象指针那样可以进行加