第二部分 认识C#与面向对象编程
第3章C#语法与面向对象编程
C#(读做“C sharp”)是一种编程语言,它是为在.NET Framework上运行的各种应用程序而设计的。C#简单、功能强大、类型安全,而且是面向对象的。C#凭借在许多方面的创新,在保持C语言风格的同时,可以实现.NET环境下应用程序的快速开发。
Visual C#是Microsoft对C#语言的实现。Visual Studio通过功能齐全的代码编辑器、编译器、项目模板、设计器、代码向导、功能强大而易用的调试器,以及其他工具,实现了对Visual C#的支持。通过.NET Framework类库,可以访问许多操作系统服务和其他精心设计的有用类,这些类可显著缩短开发周期。
3.1 C#语言概述
Microsoft公司是这样描述C#的:“C#是从C和C++派生出来的一种简单、现代、面向对象的类型安全的编程语言。C#主要是从C\C++编程语言家族移植过来的,C和C++的程序员会马上熟悉它。C#试图结合Visual Basic快速开发的能力和C++强大灵活的能力。”
它具有现代的面向对象的特点,这使得程序员能在新的微软.NET平台上快速开发出种类丰富的应用程序。由于它是从C和C++中派生出来的,因此具有C++的功能。同时,由于是Microsoft公司的产品,它又同VB一样简单。对于Web开发而言,C#像Java,同时具有Delphi的一些优点。Microsoft宣称,C#是开发.NET框架应用程序的最好语言。作为一种面向对象的语言,C#支持封装、继承和多态性的概念。所有的变量和方法,包括main方法(应用程序的入口点),都封装在类定义中。类可能直接从一个父类继承,但它可以实现任意数量的接口。重写父类中的虚方法的各种方法要求用override关键字作为一种避免意外重定义的方式。
除了这些基本的面向对象的原理之外,C# 还通过几种创新的语言结构简化了软件组件的开发,这些结构包括:
● 封装的方法签名(称为“委托”),它实现了类型安全的事件通知;
● 属性(Property),充当私有成员变量的访问器;
● 特征(Attribute),提供关于运行时类型的声明性元数据;
● 语言集成查询(LINQ),提供了跨各种数据源的内置查询功能。
3.1.1 C#语言的主要应用
正是由于C#提供了优秀的面向对象的程序设计能力,程序设计员才可以快速地编写基于Microsoft.NET平台的应用程序。在Microsoft.NET平台下,利用C#语言通常可以用于开发以下多类应用程序:
● Windows应用程序;
● WPF应用程序;
● 控制台应用程序;
● WPF用户控件库;
● 类库;
● WPF浏览器应用程序;
● Windows服务;
● WPF自定义控件库;
● Windows窗体控制库。
在本书中涉及的应用包括控制台应用程序和Windows应用程序,我们将在后面的章节中对它们做详细的介绍。
3.1.2 C#语言的优点
C#语言具有以下的一些突出优点。
1. 简洁的语法
C#的大括号语法使任何熟悉C、C++或Java的人都可以立即上手。了解上述任何一种语言的开发人员通常都能在很短的时间内就可以开始使用C#高效地进行工作。C#语法简化了C++的诸多复杂性,并提供了很多强大的功能,同时,C#支持泛型方法和类型,从而提供了更出色的类型安全和性能。
2. 巧妙的面向对象设计
在C#的类型系统中,每种类型都可以看做一个对象,C#提供了一个叫做装箱(boxing)与拆箱(unboxing)的机制来完成这种操作,而不会给使用者带来麻烦。C#只允许单继承,即一个类不会有多个基类,从而避免了类型定义的混乱。
3. 与Web的紧密结合
因为有了Web服务框架的作用,对程序员来说,网络服务看起来就像C#的本地对象。程序员能够利用它们已有的面向对象的知识和技巧开发Web服务。仅需要使用简单的C#语言结构,C#组件就能够方便地为Web服务,并允许它们通过Internet被运行于任何操作系统上的任何语言所调用。
4. 完备的安全性与错误处理能力
在C#中,变量是类型安全的。C#中不能使用未被初始化的变量,对象的成员变量由编译器负责将其置零,当局部变量未经初始化而被使用时,编译器将做出提醒。C#不支持不安全的指向,不能够将整数指向引用类型,如对象。当进行下行指向时,C#将自动验证指向的有效性。C#中提供了边界检查与溢出检查功能。
5. 灵活性与兼容性
在简化语法的同时,C#并没有失去灵活性。虽然它不能用来开发硬件驱动程序,且在默认的状态下没有指针等,但是,它仍然不失灵活性。C#不支持类的多继承,但是通过对接口的继承,实际上可以获得这一功能,这体现了它的灵活性。
3.1.3 C# 3.0的新特性
在发布Visual Studio 2008后,微软公司又及时地展示了人们所期望的C#的下一代版本:C# 3.0。尽管C# 3.0并没有标准化,但微软还是为Visual Studio 2008引入了C#的新特性,使其语言更加简洁与丰富。其新特性包括以下几个方面。
1. 隐式类型本地变量
C# 3.0引进了一个新的关键字叫做Var。Var这个关键字用于在变量最先声明时,从用来初始化变量的表达式中推断出变量的类型。
2. 扩展方法
扩展方法使用户能够使用额外的静态方法来扩展各种类型。不过它们是非常有限的,也只能在实例方法不足的情况下作为候补使用。扩展方法只能在静态类中被声明,并且以关键字this放在方法的第一个参数前来标识。
3. Lambda表达式
Lambda表达式显得更加简洁,它也可以用来产生匿名方法,但要求必须清楚地陈述每个类型的状态。
4. 表达式树
C# 3.0包含了一个新类型,允许表达式当做运行时的数据使用。这个类型,System. Expressions.Expression<T>,只是内存中一个Lambda表达式的重新表达,这样可以使代码在运行时也能修改和检查Lambda表达式。
5. 对象初始化器
C# 3.0允许new操作与匿名的对象初始化器创建一个匿名类型的对象。C# 3.0提出了对象初始化器(Object Initializers)的概念,可以指定一个或多个对象的域或属性的值。由此可见,两种初始化对象的方式完全一样。匿名对象初始化器声明一个匿名类型,并返回这个类型的实例。
3.1.4 C#程序的编译与执行
.NET语言的编译分为两个阶段,编译源文件为中间语言(IL)和CLR加载程序集。
1. 编译源文件为中间语言
IL(Intermediate Language)称为中间语言。首先所有的.NET源代码都将被编译成IL,与高级语言相比,IL更像是机器语言。然而,IL却包含一些抽象概念(如类、异常),这也是这种语言被称为中间语言的原因。IL被打包在DLL或EXE文件中,并存储在项目文件夹中。
2. CLR加载程序集
进一步将IL编译成汇编语言的工作(也就是第二阶段)需要在运行时进行,这个过程由即时编译器(JIT)完成。
执行C#程序时,程序集将加载到CLR中,这可能会根据清单中的信息执行不同的操作。如果符合安全要求,CLR就会执行实时编译(JIT)以将IL代码转换为本机机器指令。CLR还提供与自动垃圾回收、异常处理和资源管理有关的其他服务。由CLR执行的代码有时称为“托管代码”,它与编译为面向特定系统的本机机器语言的“非托管代码”相对应。
也就是说,当编译器生成一个EXE文件后,该程序的入口函数为main() 方法。装载器将这个EXE文件载入,探测到这是一个托管EXE,于是又载入.NET运行时库文件,接着调用了EXE的main()方法,这将触发对main()方法的即时编译。main()方法在内存中被替换为本地机器语言,于是.NET应用程序开始运行。当程序中止时,本地代码从内存中释放,所以在下次运行时,IL需要被即时编译器重新编译。
注意:在程序设计中进行编译时,初学者有时会遇到这样的问题,即无论在项目中做了何种修改,编译时仍按以前的结果运行。这时需要在项目文件夹中的bin子文件夹中选择debug子文件夹,将其内与项目同名的exe文件删掉重新编译才行,请读者务必注意。