Chapter 1. Introducing C# and the .NET Framewrok

C#是一种通用,类型安全,面向对象的编程语言。C#语言的目的是程序员的生产力。为了达到这一目的,C#语言是在简单性,表现性与性能之间进行平衡。由第一版开始,C#语言的主架构师是Anders Hejlsberg。

面向对象

C#是一种面向对象范例的富实现,其包含封装,继承与多态。封装意味着在对象周围创建一个边界来将其外部(公开的)行为与其内部(私有的)实现细节相分离。由面向对象的角度来看,C#独具的特性是:

统一类型系统

C#语言中基础构建块是数据与函数的封装单元,被称之为类型。C#具有统一的类型系统,其中所有的类型最终都会共享一个通用的基类型。这就意味着所有的类型,无论他们表示业务对象或是基本类型,例如数字,都共享相同的基本功能集合。例如,所有的类型都可以通过调用其ToString方法转换为一个字符串。

类与接口

在纯面向对象的范例中,唯一的类型种类就是类。在C#中,还有其他的类型种类,interface就是其中之一(类似于Java的接口)。接口类似于一个类,所不同的是他只是类型的定义,而不是实现。在需要多继承时,接口就显得十分用(与C++或Eiffel不同,C#不支持类的多继承)。

属性,方法与事件

在纯面向对象范例中,所有的函数都是方法(在Smalltalk中是这种情况)。在C#语言中,方法只是一种类型的函数成员,函数成员还包括属性与事件(也还有其他的)。属性是封装了一个对象状态的片段的函数成员,例如按钮的颜色或是标签的文本。事件是简化对象状态改变上的响应的函数成员。

类型安全

C#根本上是一种类型安全的语言,意味着类型只能通过他们所定义的协议进行交互,从而保证每种类型的内部一致性。例如,C#不允许我们与一个字符串类型交互,尽管他是一个整数类型。

更为特殊的,C#支持静态类型,意味着语言强制编译时类型安全。这是对.NET CLR所强制的运行时类型安全的补充。

静态类型减少了大量程序运行之前的错误种类。他将负担由运行时单元测试转移到编译来验证程序中的所有类型正确的组合。这使得大程序更容易管理,更可预测,以及更健壮。而且,静态类型使得类似Visual Studio中的IntelliSense这样的工作可以帮助我们编写程序,因为他知道一个指定的变量是什么类型,从而了解在这个变量上我们可以调用哪些方法。

注意:C# 4.0允许我们通过新的dynamic关键使得我们的部分代码成为动态的。然而,C#保留了静态类型语言的优势。

C#被称之为强类型语言,因为其类型规则非常严格。例如,我们不能使用一个浮点数来调用被设计用来接受整数的函数,除非我们有首先显式的将浮点数转换为整数。这有助于避免失误。

强类型同时在使得C#代码运行在沙盒中扮演重要角色-所谓的沙盒是一种环境,其中所有的安全方面都由主机控制。在沙盒中,很重要的一点就是我们不能通过略过类型规则来任意的破坏对象的状态。

内存管理

C#依赖运行时来执行自动内存管理。CLR具有一个作为我们程序的一部分来执行的垃圾收集器,回收不再被引用的对象所占用的内存。这将程序由显式的释放对象所占用的内存中解放出来,减少了在类似C++的语言中所遇到的不正确的指针的问题。

C#并没有清除指针:仅是使得指针对于大多数程序任务来说并不是必需的。对于性能要求较高的任务,也可以使用指针,但是他们只可以在显式标识非安全的块中。

平台支持

C#通常用于编写运行在Windows平台上的代码。尽管微软通过ECMA标准化了C#语言与CLR,但是在非Windows平台上致力于支持C#的资源问题要相对少得多。这意味着当跨平台是主要关注点时,Java语言将是明智的选择。尽管如此,C#可以在下列情况下用于编写跨平台代码:

  • C#代码也许可以运行在服务器上并且装载可以在任意平台上的DTHML。更确切的说是ASP.NET。
  • C#代码也许运行在除微软公共语言运行时以外的运行时上。最值得注意的例子就是Mono项目,其具有自己的C#编译器与运行时,运行在Linux,Solaris,Mac OS X以及Windows上。
  • C#代码可以运行在支持微软Silverlight的主机上。这是一种类似于Adobe的Flash Player的新技术。

C#与CLR的关系

C#依赖装备了例如自动内存管理与异常处理等特性的主机的运行时。C#的设计近似的映射到CLR的设计,他提供了这些运行时特性(尽管在技术上C#是独立于CLR的)。而且,C#类型系统近似映射到CLR类型系统(例如,两者都共享基本类型的相同定义)。

CLR与.NET框架

.NET框架由被称之为公共语言运行时(CLR)的运行时以及大量的库集合构成。库由核心库(本书所关注的)以及依赖核心库的应用库所构成。图1-1是这些库的一个可视化概览。

CLR是用于执行托管代码的运行时。C#是可以被编译为托管代码的托管语言之一。托管代码会以可执行文件或库的形式,同时带有类型信息或是元数,被打包为一个集合。

托管代码以中间语言或IL表示。当CLR装载一个集合后,他会将IL转换为机器的本地代码,例如x86。这个转换是通过CLR的JIT(Just-In-Time)编译器完成的。集合保存有几乎所有的原始的源语言结构,从而使其更容易检测,甚至动态生成代码。

CLR作为大量运行时服务的主机。这些服务的例子包括内存管理,库装载以及安全服务。

CLR是语言无关,允许开发人员使用多种语言构建程序。

.NET框架由用于编写Windows或基于Web的程序的库组成。第5章会提供.NET框架库的概述。

C# 4.0中的新特性

C# 4.0中的新特性有:

  • 动态绑定
  • 具有通用接口与委托的类型变化
  • 可选参数
  • 命名参数
  • COM交互性的改进

动态绑定是C# 4.0最大的变化。这一特性来自动态语言的启发,例如,Python,Ruby,JavaScript,以及Smalltalk。动态绑定将绑定-解析类型与成员的过程-由编译时推迟到运行时。尽管C#保留了静态类型语言的优点,但dynamic类型的变量以后绑定的方式解析。例如:

dynamic d = "hello";
Console.WriteLine (d.ToUpper());  // HELLO
Console.WriteLine (d.Foo());      // Compiles OK but gives runtime error

动态调用对象在复杂的反射代码的情况下十分有用。当与动态语言与COM组件交互时,动态绑定也十分有用。

可选参数允许函数指定默认参数值,从而调用者可以忽略参数。可选参数声明如下:

void Foo (int x = 23) { Console.WriteLine (x); }

而调用方式如下:

Foo(); // 23

命名参数允许函数调用者通过名字而不是位置来标识参数。例如,前面的方法可以以下面的方式调用:

Foo (x:5);

类型变化可以使得通用接口与通用委托将他们的类型参数作为变量。例如下面的代码:

IEnumerable<string> x = ...;
IEnumerable<object> y = x;

COM交互性在C# 4.0中以三种方式得到了加强。首先,参数通过引用传递,而无需ref关键字。这个特性在与可选参数结合使用时特别有用。这意味着下面的打开一个Word文档的C# 3.0代码:

object o1 = "foo.doc";
object o2 = Missing.Value;
object o3 = Missing.Value;
...
word.Open (ref o1, ref o2, ref o3...);

可以简化为

word.Open ("Foo.doc");

第二,包含COM交互操作类型的集合现在可以链接(linked)而不是引用(referenced)。链接的交互操作类型支持类型等价,避免了基本的类型操作集合的需要以及结束了版本与部署的麻烦。

第三,返回链接操作类型中的variant类型的函数被映射到dynamic而不是object,避免了转换的需要。