本节书摘来异步社区《Visual C# 2010入门经典》一书中的第1章,第1.2节,作者: 【美】Scott Dorman
译者: 张劼 责编: 傅道坤,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.2 C#语言
Visual C# 2010入门经典
如果您是C、C++或Java程序员,将很快熟悉C#,因为其语法与这些语言类似。如果您熟悉Visual Basic(运行在.NET Framework上的任何Visual Basic版本,而不是Visual Basic 6.0或更早的版本),可能对C#语法感到陌生,但应熟悉Framework类库。如果您从未使用过上述任何语言,也将发现与众多其他语言相比,使用C#进行编程更容易,因为它语法优雅,类库庞大。
**
提示:语言灵感**
作为一种语言,C#借鉴了众多不同的语言,以形成其语法和主要功能,这包括Delphi 5、C++和Java 2。
泛型系统(第11章将更详细地介绍)是从Eiffel和Ada那里借鉴而来的;而LINQ和Lambda表达式评估(参见第12章)主要是从Haskell和Lisp那里借鉴而来的。
C#还添加了一些来自动态语言(如Ruby)和函数语言(如F#)的功能。
与众多现代编程语言一样,C#也是一种面向对象的语言,全面支持面向对象编程概念,如继承、多态、封装和抽象。另外,C#还支持面向组件编程,这让您能够指定自带文档的独立功能单元(组件),为此只需提供一个模型,它包含属性、方法、事件以及有关组件的元数据。C#本身就支持这些概念,这使得创建和使用组件的过程非常自然。如果您不熟悉这些概念,请参阅第3章。
C#提供的语言功能让开发人员能够利用CLR的改进。垃圾收集功能自动管理内存;异常处理提供了一种可扩展的结构化方法,让您能够检测错误并从错误中恢复。作为一种类型安全语言,下述情况根本不可能发生:变量未初始化、非法访问内存、将一种类型的数据存储到只能接受另一种类型的地方。
另外,C#的语言功能和语法设计还减少了您需要编写的代码量,这让代码更简单,降低了发生常见错误的可能性。在有些情况下,这种改进不过是改变语法:简化复杂或容易出错的语言功能,让它们更容易使用和理解;在其他情况下,这种改进提供了更高级的功能。
每个新的C#版本都做了改进:新增语言功能、改进语法,致力于让简单的事情容易、让困难的事情变得可能、让糟糕的事情难以发生。随着C#不断新增功能,简单的事情变得更容易了,困难的事情变得容易了,以前不可能的事情变得可能了。
1.2.1 类型
在C#中,类型是对值的描述。每当您需要一个值时,就需要一种类型。正如前面介绍通用类型系统时指出的,类型定义了允许的值以及这些值支持的操作。在C#中,每个值都由其所属的类型全面描述,且是其所属类型的一个实例。所谓全面描述,指的是类型明确地指定了值的表示方式以及可对它执行的操作。
C#类型分两类:值类型和引用类型。值类型描述的值是完全独立的,这包括数值类型、枚举类型和结构;引用类型存储指向值的引用,而不是值本身。
提示:
第2章更深入地探讨了值类型和引用类型之间的差别。
C#提供了众多预定义的值类型和几种预定义的引用类型,您还可以创建用户定义的类型。在接下来的几章中,将更详细地探讨值类型和引用类型之间的差别以及如何创建用户定义的类型。但就目前而言,只需知道一个最重要的差别:值类型包含实际值,而引用类型包含指向实际数据的引用。
1.2.2 语句和表达式
语句是一条完整的程序指令,必须以分号(;)结尾。每条语句中只能包含一条指令,这看起来限制性很强,但C#还提供了语句块,这是一组用大括号括起的语句。在可以使用单条语句的任何地方都可使用语句块。
由于语句以分号结尾,因此可使用空白(如空格、制表符和换行符)调整代码的排列方式。最佳的方法是采用一种简单而一致的风格(如果您的公司或团队没有这样的风格),让代码更容易阅读和维护。
警告:空白
虽然编译器通常忽略空白,但是类型声明、标识符和其他关键字之间的空白很重要。如果没有空白,编译器将无法识别关键字。
表达式的结果为值。如果将语句视为操作,那么表达式就是计算。结果为布尔值(true或false)的表达式常用于判断条件是否满足,这种表达式称为布尔表达式。
1.2.3 变量和常量
对于变量,最简单的定义是它表示一个存储位置,其中的值可随时间流逝而变化。最常见的变量是局部变量和字段,它们都可通过指定类型、标识符和可选的初值来定义:
int a;
int b = 1;
如果要声明多个类型相同的变量,就可将声明合并在一起,如下所示:
int a, b;
在限定作用域(如方法)内声明的变量称为局部变量,只能在该作用域内通过名称访问它。
注意:作用域、声明空间和寿命
可将作用域视为容器,只有在该容器内才能通过非限定名合法地访问变量。这不同于声明空间,在声明空间内,不允许有两个名称相同的标识符。如果说作用域指定了您在哪里能够使用某个名称,那么声明空间就指出了该名称在哪里是唯一的。
变量的寿命与其作用域紧密相连,它决定了变量在多长时间内可用。只要当前执行的代码还位于变量的作用域内,该变量就可用。
第3章将更详细地介绍作用域和声明空间。
字段是在限定作用域内声明的变量,它要么与类型本身相关联,要么与类型的一个实例相关联。在前一种情况下称为静态变量(可将其视为一种全局变量);在后一种情况下则称为实例变量。使用局部变量和字段之前,必须将其初始化;另外,只有在这些变量的声明所属的代码块内才能访问它们。
程序清单1.1是一个名为Color的类型,其中包含私有实例字段red、blue和green,还包含公有静态字段White、Red、Blue和Green。
程序清单1.1 Color类
使用静态字段之前,需要对其进行初始化,但是此后无法保证它们的值不会变化。为了声明初始化后就不能修改的字段,可以创建只读字段。
提示:
有关只读字段的更详细信息,请参阅第3章。
程序清单1.2列出了Color类中被修改的代码行。
程序清单1.2 使用只读字段的Color类
常量表示在编译阶段可计算的值。常量与类型本身相关联,就像是静态的。与变量一样,常量可在限定作用域内声明,也可以是全局的;与变量不同的是,必须在声明常量时对其进行初始化。
提示:字面值和魔数
字面值通常是有特殊含义的数值,并在代码中直接指定。随着时间的推移,可能忘记字面值的含义,导致相应的代码难以维护。因此,这些字面值常被称为魔数(magic numbers)。通过使用常量而不是字面值,可将其含义保留下来,让代码的含义不言自明。
对于下述函数中的数字,您花了多长时间才弄明白其含义呢?
如果使用常量重新编写该函数,其中的魔数的含义将非常明显:
在这个示例中,299792458是一个字面值,因此可将其视为一个魔数。您可能猜到了,应使用常量而不是字面值,因为与数字相比,常量的名称可更好地说明其含义,还可确保其值不会变化。
声明变量或常量的语句通常称为声明语句,可位于代码块的任何地方。
1.2.4 标识符和关键字
声明变量、字段或常量时,必须指定数据类型并提供有意义的名称,后者称为标识符。
标识符必须遵循如下规则。
- 只能包含字母(大写和小写)、数字和下划线。
- 标识符必须以字母或下划线打头,但对于公有标识符,以一个或多个下划线- 打头是一种糟糕的做法,应避免这样做。
- 在给定的声明空间内,标识符必须是唯一的。
- 标识符是区分大小写的。
选择标识符时,还应遵守的其他指导原则如下。
- 标识符应易于阅读。
- 标识符应使用缩写。
- 标识符应提供尽可能丰富的含义。
在C#中,标识符是区分大小写的。推荐的命名约定建议如下:对于变量名和参数名,使用Camel大小写规则,该规则要求除第一个单词外,其他单词的首字母都大写,如bookTitle;对于方法名和其他标识符,使用Pascal大小写规则,该规则要求每个单词的首字母都大写,如BookTitle。
提示:Camel和Pascal大小写规则
采用Camel大小写规则时,标识符中的大写字母看起来向驼峰,这种大小写规则因此而得名。Pascal大小写规则因其被Pascal编程语言广泛采用而得名(Turbo Pascal语言最初是由Anders设计的)。
Microsoft不再推荐使用Hungarian表示法,也不推荐使用下划线分隔单词,这两种表示法在其他语言中很常用。
如果您熟悉其他区分大小写的语言,如C、C++或Java,就会觉得这很正常;如果您以前使用的是不区分大小写的语言,如Visual Basic,可能需要一段时间才能适应。所幸的是,Visual Studio 2010代码编辑器提供的功能可让这种过渡更容易。
由于标识符定义了特定元素的名称,因此C#也需要使用标识符向编译器和您表示特殊含义,它保留了一些标识符供自己使用,这些标识符称为关键字。
在C#中,有77个标识符在任何情况下都属于关键字,如表1.2所示。
另外,还有24个关键字称为上下文关键字,它们仅在特定情况(上下文)中有特殊含义。离开该上下文后,这些关键字就可供您使用,但为避免混淆,应尽量避免使用。表1.3列出了这些上下文关键字。