C#和NET35高级程序设计(第4版)笔记

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《C#和.NET3.5高级程序设计(第4版)》笔记1
疯狂代码 / ĵ:http://BlogDigest/Article76071.html
第一章 .NET之道本章的目的在于为本书其余部分建立起一个概念性的框架,由.NET之前各种技术的局限性和复杂性开始,然后综述了.NET和C#是如何试图简化这种状况的。

;以前看过不少.NET相关书籍,一般第一章都是简述.NET,但是比较凌乱,概念也不统一,在原有的理解基础上,从这本书中又得到一些新的理解。

虽然是第一章,但是许多概念都很重要,因此多引用一些原文,并对一些概念进行了扩充,以求在之后的学习中,不会有太多混淆之处。

以后的笔记中,将有重点的进行记录。

;1. 1 ; .NET之前的世界 ;C/Win32 API
API:费时、费力、复杂,数以千计的全局函数和数据类型。

C:简练,手动内存管理、指针运算、复杂语法、非面向对象。

C++/MFC
C++:面向对象,手动内存管理、指针运算、复杂语法。

MFC(微软基础类):提供一组c++类,把Win32 ;API 的一个健全子集包装成类、宏、代码生成工具(向导),来简化win32开发。

VB6
VB:降低复杂性,通过集成代码向导内置数据类型、类和vb专门函数把原始win32 api的复杂性隐藏起来。

并非完全面向对象(中已经解决),没有继承,不内置参数化构造,不支持开发多线程程序。

注:这里之所以以VB6这个版本作为标题,可能是因为他的流行程度太高了把,这也是.NET推出后采用之前的最后一个VB版本。

JAVA/J2EE
java:面向对象,句法结构源于c++,去掉许多复杂语法,提供预定义的各种“包”来实现诸多功能。

平台无关。

前台后台开发都必须选用java。

与其他语言集成的支持差。

COM
COM(组件对象模型):应用程序开发框架,可复用的二进制模块。

有限的语言无关方式访问,不支持继承。

位置透明。

过于复杂,脆弱的组件注册问题与部署问题(dll地狱)。

笔者补充:COM+:与 COM 一样,COM+基于二进制组件和基于接口的编程。

通过使用透明 RPC 层,可以跨越进程和计算机边界进行远程方法调用。

正如 COM 组件那样,COM+ 组件可以在成品中升级和扩展,而不会对使用它们的客户端应用程序造成负面影响。

Windows DNA
DNA:使用基于COM的Windows分布式因特网应用架构。

复杂,需要使用很多相关技术和语言,令人迷惑的技术大杂烩。

;1. ;2 ; .NET解决方案对已有代码具有完全的互操作性
与现有COM组件并存,并利用平台调用(PInvoke)服务调用基于C的库和操作系统的底层API。

虽然.net不提倡使用win32 api,但现在的.net framework没有完全覆盖所有的win32 api,而且一些场合使用win32 api还是最简单高效的方法。

相信做老系统升级的程序员对此一定深有感触。

完全的语言集成
跨语言的继承、异常处理、调试。

.net 支持语言无关和语言集成,你可以继承一种符合.net 公用类型系统(CTS)的语言写的类,捕获他的异常,使用跨语言的多太性。

也就是说在.net环境下各种语言是可以混合使用的,你可以从完全不同的语言写成的基类派生一个类,也可以在程序里捕获用另一种语言编写的异常等等。

具体可以参考: 《感受.net的跨语言特性》
所有支持.NET的语言共享的公共运行时引擎
明确定义的类型,被每种支持的语言共享。

全面的基类库
隐藏API的复杂性,被所有支持语言所使用的一致对象模型。

不关注COM底层操作
真正简化的部署模型
不需要将二进制单元注册到注册表。

允许同一个*.dll的不同版本共存。

1. ;3 ; .NET平台构成(3C)这里总是又许多的概念,但是一些书总是讲不清楚关系,这本书讲的还是比较易懂的。

从整体上可以理解.NET(或framework)是由运行库环境和基类库构成。

具体的来说,.NET由三个关键实体(3C):CLR、CTS和CLS构成。

具体关系如下图: ; ; CLR:CLR(公共语言运行时,Common Language Runtime)和Java虚拟机一样也是一个运行时环境,保证应用和底层操作系统之间必要的分离,它负责定位、加载和管理.NET类型,同时负责一些底层的细节工作,如内存管理、创建应用程序域、线程和对象上下文边界、安全检查等。

; 在CLR监视之下运行的程序属于“受管理的”(managed)代码,而不在CLR之下、直接在裸机上运行的应用或者组件属于“非受管理的”(unmanaged)的代码。

当然,这种对受管理代码的运行监视是有一定代价的,必然影响一些性能,但是是可接受范围。

; CTS: ;.NET平台的另一个构造块是CTS(公共类型系统)。

NET结合Java和COM解决方案两者优点来解决互操作性问题。

类似于COM定义的标准二进制格式,.NET定义了一个称为通用类型系统Common Type System(CTS)的类型标准。

CTS规范完整地描述了运行库所支持的所有可能的数据类型和编程结构,指定了这些实体间如何交互,也规定了它们在.NET元数据格式中的表示。

这个类型系统不但实现了COM的变量兼容类型,而且还定义了通过用户自定义类型的方式来进行类型扩展。

任何以.NET平台作为目标的语言必须建立它的数据类型与CTS的类型间的映射。

所有.NET语言共享这一类型系统,实现它们之间无缝的互操作。

该方案还提供了语言之间的继承性。

例如,用户能够在中派生一个由C#编写的类。

; ;CLS: ;很显然,编程语言的区别不仅仅在于类型。

例如,一些语言支持多继承性,一些语言支持无符号数据类型,一些语言支持运算符重载。

用户应认识到这一点,因此.NET通过定义公共语言规范(CLS:Common Language Specification),限制了由这些不同引发的互操作性问题。

CLS制定了一种以.NET平台为目标的语言所必须支持的最小特征,以及该语言与其他.NET语言之间实现互操作性所需要的完备特征。

认识到这点很重要,这里讨论的特征问题已不仅仅是语言间的简单语法区别。

例如,CLS并不去关心一种语言用什么关键字实现继承,只是关心该语言如何支持继承。

;要注意的是,一种特定的支持.NET的语言可能不支持CTS所定义的所有特性。

CLS(公共语言规范)是一个相关的规范,定义了一个让所有的.NET语言都支持的公共类型和编程结构的子集。

这样,如果构造的.NET类型仅暴露与CLS兼容的特性,那么可以肯定其他所有支持.NET的语言都能使用它们。

反之,如果使用了与CLS不兼容的数据类型或编程结构,就不能保证所有的.NET语言能和你的.NET代码库相交互。

CLS是CTS的一个子集。

这就意味着一种语言特征可能符合CTS标准,但又超出CLS的范畴。

例如:C#支持无符号数字类型,该特征能通过CTS的测试,但CLS却仅仅识别符号数字类型。

因此,如果用户在一个组件中使用C#的无符号类型,就可能不能与不使用无符号类型的语言(如)设计的.NET组件实现互操作。

这里用的是“可能不”,而不是“不可能”,因为这一问题实际依赖于对non-CLS-compliant项的可见性。

事实上
,CLS规则只适用于或部分适用于那些与其他组件存在联系的组件中的类型。

实际上,用户能够安全实现含私有组件的项目,而该组件使用了用户所选择使用的.NET语言的全部功能,且无需遵守CLS的规范。

另一方面
,如果用户需要.NET语言的互操作性,那么用户的组件中的公共项必须完全符合CLS规范。

疑问:既然说了CTS规范完整地描述了运行库所支持的所有可能的数据类型和编程结构,又说某种特定的支持.NET的语言可能不支持CTS所定义的所有特性,那么是不是说某些支持.NET的语言不能被运行库支持?应该正确看待“3C”。

开发人员在构建自己的分布式应用程序时,因为用户在编程时将直接面对CLR,应将主要精力放在学习了解CLR上,而不是CTS和CLS。

而对于希望以.NET平台为目标的语言和工具开发商来说,就需要深入理解CTS和
CLS。

互操作性组件是分布式应用的关键,因此理解.NET如何通过定义公共类型实现这一目标,也就显得十分重要。

;BCL:除CLR和CTS/CLS规范之外,.NET平台提供了一个适用于全部.NET程序语言的基类库(BCL)。

这个基类库不仅封装了各种基本类型,如线程、文件输入/输出(I/O)、图形绘制以及与各种外部硬件设备的交互,还支持在实际应用中用到的一些服务。

例如,在基类库中定义了一些类型,方便了数据库访问、XML文档的操作、安全和基于Web(以及传统的桌面和基于控制台)的前端的构造。

;1. ;4 ; .NET支持的编程语言 ;由于.NET与以前的技术有着极大的差异,微软特意为.NET平台开发了一种新的编程语言--C#(读做"C Sharp")。

C#的核心语法和Java的语法很相似。

然而,没有一种语言是凭空创造的,同时,也没有一种语言是完全复制现有的语言,并不能说C#抄袭了Java。

C#和Java都属于C语言系列(包括C、Objective C、C++等),它们有类似的语法。

正如Java在许多方面是C++的提炼版一样,C#也可以视为Java的提炼版。

;实际上,C#的许多语法结构与VB 6.0和C++的很多方面都有渊源。

例如,与VB6类似,C#支持正式的类型属性(property) 的概念(与传统的获取方法和设置方法相反),且支持方法带有不定数目的参数(使用参数数组)。

与C++类似
,C#允许重载运算符,且支持创建结构、枚举和回调函数(使用委托)。

;C#是多种语言的混合体,因此它像Java一样语法简洁,像VB6一样使用简单,像C++一样功能强大和灵活(C#没有像C++那样麻烦的位操作)。

以下是C#核心特征的一部分,其中大部分特点也是其他支持.NET的程序语言所共有的特征。

不需要指针
!C#程序通常不需要直接对指针进行操作(尽管在绝对必要时也能自由地进行底层操作)。

垃圾收集器能够自动管理内存。

因此,C#不支持delete关键字。

类、接口枚举、结构和委托都有正式的语法结构。

具有与C++类似的功能,可以简单地重载运算符为自定义类型(例如,不需要操心确保"返回*this以能够链接")。

支持基于特性的编程。

这种方式的开发允许我们注释类型及其成员来进一步限定其行为。

随着.NET 2.0的发布(大约在2005年),C#编程语言得到了更新以支持很多花哨的东西,主要是以下几项。

构建泛型类型和泛型成员的能力。

使用泛型,我们可以构建非常高效的并且类型安全的代码,在和泛型项交互的时候可以定义很多"占位符"。

支持匿名方法,它允许我们在任何需要委托类型的地方提供内联函数。

很多委托/事件模型的简化,包括协变、逆变以及方法组转换。

使用partial关键字跨多个代码文件定义单个类型的能力(或者如果有必要的话,可以作为内存中的表示)。

你也可能猜到了,.NET 3.5为C#编程语言(更确切地说是C# 3.0)增加了更多功能,包括如下特性。

支持强类型的查询(就像LINQ,即集成查询语言),可用于和各种形式的数据进行交互。

支持匿名类型,它允许我们建模一个类型的"形"(shape)而不是其行为。

使用扩展方法扩展既有类型功能的能力。

包含了Lambda运算符(=>),它可以进一步简化.NET委托类型的使用。

新的对象初始化语法,它允许我们在对象创建时设置属性的值。

关于C#语言,要理解的最重要的一点可能是,它生成的代码只能在.NET运行库中执行(你不能用C#来构建本机的COM服务器或非托管的Win32 API应用程序)。

正式的说法是,这种必须在.NET运行库下执行的代码称为托管代码(managed code)。

这些包含托管代码的二进制单元可以称为程序集(assembly)。

反之,不能直接在.NET运行库承载(host) 的代码称为非托管代码(unmanaged code)。

;应该知道,C#并不是构建
.NET应用的唯一一种语言。

软件开发商宣称他们已经或者正在开发各自支持.NET的编译器。

目前,有多种不同的语言支持.NET。

除了与Microsoft .NET Framework 3.5 SDK一起发布的5种语言(C#、Visual Basic
.NET、J#、C++/CLI(以前称为托管C++)和JScript .NET)之外,还有Smalltalk、COBOL和Pascal的
.NET编译器等。

;多语言的支持主要有两点考虑: ;一方面,程序员在选择编程语言时有各自不同的喜好(包括我自己)。

另一个好处,就是能够取长补短。

所有的编程语言都有各自的优点和缺点。

例如,一些编程语言对高级的数学处理有相当完美的内在支持能力。

另一些则精于支持财务计算、逻辑计算和与大型机交互等。

当你学习到某种编程语言的优点并将其融合于.NET平台时,大家就都能受益。

; ;1. ;5 ; .NET程序集这个程序集的概念是我学.NET基础概念时遇到的最大困惑,为什么总是被将不明白,乱七八糟。

《C#与.NET3.5高级程序设计(第4版)》这本书让我第一次对他有了比较好的理解! ;当使用支持.NET的编译器生成*.dll或*.exe文件时,生成的模块会被打包成一个程序集。

这里需要理解这个新文件格式的基本属性。

不管选择了哪种.NET语言编程,需要明白的是,尽管.NET二进制文件与COM服务器和非托管Win32二进制文件(*.dll或*.exe)具有相同的文件扩展名,但它们的内部却是完全不同的。

*.dll的.NET二进制文件不会导出与COM运行库进行通信的方法(因为.NET不是COM)。

.NET二进制文件不使用COM类型库文件描述而且不用在系统注册表中注册。

.NET二进制文件不包含特定于平台的指令,它包含的是平台无关的IL(中间语言)和类型元数据。

下图清楚显示了这个流程。

; ; ;单文件程序集和多文件程序集大多数情况下,一个程序集只对应一个二进制文件(*.dll或*.exe)。

因此,当生成一个.NET *.dll时,可以认为二进制文件和程序集完全一样。

同样,当生成一个可执行文件时,可以简单认为这个*.exe就是程序集本身。

此处的说法并不很确切,在第15章中将会详细说明这一点。

从技术角度讲,如果程序集由一个*.dll或*.exe模块构成,就会得到一个单文件程序集。

单文件程序集是一个独立、单一且定义明确的包,这个包中包含所有必需的CIL、元数据和相关的程序集清单。

;另一方面,多文件程序集则由多个.NET二进制文件组成,其中的每个二进制文件称作模块(module)。

生成一个多文件程序集时,其中一个模块(称为主模块)一定包含程序集清单(还可能包含CIL指令和各种类型元数据)。

其他相关的模块包含一个模块级的程序集清单、CIL和类型元数据。

可以想到,主模块会记录程序集清单中所含的其他必要的辅助模块。

;那么,为什么选择创建多文件程序集呢?当把一个程序集分成几个单独的模块时,你会发现部署时可以更加灵活。

例如,当用户在调用一个需要下载到本地机器的远程程序集时,运行库只会下载所需的模块。

因此,可以随意构造程序集,即把使用率不高的类型(如名为HardDriveReformatter的类型)保存在一个模块中。

;相反,如果所有类型都存储在单文件程序集中,那么终端用户可能需要下载一大堆他们并不真正需要的数据(这显然很浪费时间)。

由此可见,程序集实际上是由一个或多个相关模块构成的一个逻辑组,这些模块将作为一个单元进行初始部署和版本管理。

疑问:如何生成和使用多文件程序集? ;程序集包括三个部分:CIL、元数据、清单。

;CIL:需要说明的一点是"IL"的缩写。

在.NET的开发过程中,IL的官方术语是MSIL(微软中间语言)。

然而在最终发布的.NET中,该术语改为了CIL(公共中间语言)。

因此,当阅读.NET资料时
,你应该明白IL、MSIL和CIL指的是同一个概念。

为了与当前术语一致,我将使用缩写"CIL"贯穿全文。

程序集包含CIL代码,后者在概念上类似于Java的字节码,因为它只在绝对必需的情况下才编译为特定平台的指令。

"绝对必需"通常是指一段CIL指令(例如一个方法实现)被.NET 运行库引用时。

CIL是一种和平台无关的语言。

不管使用何种支持.NET的语言,相关编译器(c#的csc.exe、的vbc.exe)都生成CIL指令。

编译代码后,就会得到一个单文件*.exe程序集,其中包含一个程序集清单、CIL指令和描述Calc与Program类的各方面信
息的元数据。

各种语言按照各自语法完成的相同程序,起CIL基本上是一样的!CIL的好处到此,你可能很想弄清楚,不直接把源代码编译为特定的指令集而是编译为CIL的好处到底在哪里。

有一点好处就是语言的集成性。

如前面讲过的,每种支持.NET的编译器生成的是几乎完全相同的CIL指令。

因此,所有语言都能很好地在定义明确的二进制文件间相互交互。

;此外,CIL是平台无关的,.NET Framework本身也是平台无关的。

Java程序员早已体会到了这一点好处(例如,一个代码库就可以在多种操作系统上运行)。

实际上,已经存在C#语言的国际标准和大量的.NET平台和实现的子集,它们可以供许多非Windows的操作系统使用。

与Java相比不同的是,.NET还允许用户使用自己选择的语言构建应用程序。

;将CIL编译成特定平台的指令由于程序集包含的是CIL指令而不是某一特定平台的指令,CIL代码必须在使用之前进行即时编译。

将CIL代码编译成有意义的CPU指令的工具称为即时(JIT)编译器,有时也昵称为Jitter。

.NET运行库环境将使用针对各种不同CPU的JIT编译器,每个编译器都会针对底层平台进行优化。

;比如,在手持设备(如Pocket PC)上部署一个.NET应用程序,就可以配备相应的JIT以在低内存环境下运行。

如果为后台服务器部署程序集(通常内存不是问题),那么JIT又能进行优化,使代码在高内存环境下运行。

这样,开发人员只需编写一套代码,就能在不同体系结构的设备上通过JIT编译器高效地编译和执行。

另外,当给定的JIT编译器将CIL指令编译为相应的机器代码时,它会用适合目标操作系统的方式将结果缓存在内存中。

这样,如果PrintDocument()方法被调用,则它对应的CIL指令将在第一次调用中被编译成特定平台的指令并被保留在内存中以备以后使用。

因此,在下一次调用PrintDocument()时,就不需要编译CIL了。

;说明 ;同样可以使用.NET Framework 3.5 SDK附带的ngen.exe命令行工具在安装程序时执行"预JIT"。

这样做可以改善图形密集的应用程序的启动时间。

元数据:除CIL指令以外,.NET程序集还包括全部完整且准确的元数据,这些元数据描述了每一个二进制文件中定义的类型(类、结构、枚举等),以及每个类型的成员(属性、方法、事件等)。

值得庆幸的是,生成最新的和最大的类型元数据总是编译器的工作而不是程序员的工作。

因为.NET元数据非常详细,所以程序集完全成了自描述的实体。

.NET元数据相对于COM类型元数据是一次巨大飞跃。

你可能早就知道,COM二进制文件通常使用关联类型库(它与接口定义语言[IDL]代码的二进制形式基本一样)进行描述。

COM类型信息的问题是不能保证其存在,而且IDL代码无法记录当前COM服务器正确操作所需的外部引用服务器。

相比较而言,.NET元数据总是存在并且会由某种支持.NET的编译器自动生成。

元数据不仅用于.NET运行库环境的许多方面,而且用于各种开发工具中。

例如,诸如Visual Studio 2008等工具提供的智能感知(IntelliSense)特性就能在设计阶段读程序集的元数据。

各种对象浏览工具、调试工具以及C#编译器自身都使用元数据。

需要注意的是,元数据是许多.NET技术的支柱,这些技术包括WCF、XML Web服务/远程处理层、反射、晚期绑定和对象序列化。

;清单:最后,除CIL和类型元数据之外,程序集本身也使用元数据进行描述,这类元数据的正式名称是清单(manifest)。

请记住.NET程序集也包含描述程序集自身的元数据(称为清单)。

在许多细节中,清单记录了所有确保现有程序集正常工作的外部程序集、程序集的版本号、版权信息等。

同类型元数据一样,生成程序集清单也是编译器的工作。

清单记录了程序集的当前版本信息、文化信息(用于本地化字符串和图像资源)和正确执行所需的外部引用程序集的列表。

;在后面将使用各种各样的工具(如ildasm.exe)来检验程序集的类型、元数据和清单信息。

; ; 1. ;6 ; CTS ;一个给定的程序集可能包含任意数量的不同"类型"。

在.NET领域里,类型(type)是一个一般性的术语,它指的是集合{类,接口,结构,枚举,委托}里的任意一个成员。

当用支持.NET的语言构建解决方案时,很有可能要与这些类型打交道。

例如,程序集可能定义了一个类,它又实现了一些接口。

或许其中某个接口方法采用枚举类型作为输入参数,而在调用时返回一个结构。

;CTS(公共类型系统)是一个正式的规范,它规定了类型必
须如何定义才能被CLR承载。

通常,只有那些创建针对.NET平台的工具或编译器的人才对CTS的内部工作非常关心。

但是,对于所有.NET编程人员来说,学习如何在自己使用的语言中使用由CTS定义的5种类型,是非常重要的。

这里简单概括一下。

;1.6.1 ; CTS类类型每一种支持.NET的语言至少要支持类类型(class type)的概念,这是面向对象编程(OOP)的基础。

类可能由很多成员(诸如属性、方法和事件)和数据(字段)组成。

在C#中,使用class关键字来声明类:下表给出了有关类类型的一些特征。

; CTS类类型 ;1.6.2 ; CTS接口类型接口(interface)就是由抽象成员定义所组成的一个具名集合,可通过一个给定的类或结构来支持(即实现)。

与COM不同,.NET接口并不派生公共的基接口(如IUnknown)。

在C#中,接口类型使用interface关键字来定义,例如: ;就它们自身而言,接口没有什么用。

然而,当一个类或结构用其独特方式来实现一个给定接口时,你将能够以多态方式通过接口引用来请求使用所提供的功能。

1.6.3 ; CTS结构类型CTS中还支持结构(structure)的概念。

如果你有C语言的背景,应该会很高兴地发现这种用户自定义类型(UDT)也存在于
.NET领域中(虽然它们的行为在底层不同)。

简单地说,结构(struct)可以看作是具有值语义的轻量级类类型。

关于结构的细节,请参见第4章。

通常,结构最适合建模几何和数学数据,在C#中使用struct关键字创建:;1.6.4 ; CTS枚举类型枚举(enumeration)是一种便利的编程结构,它可以用来组成名称/值对。

例如,假设你在开发一个视频游戏的程序,要让玩家在3种角色(Wizard、Fighter或Thief)中选择一个。

你完全可以用enum关键字来建立一个自定义的枚举,而不用老是要记着代表每种可能性的原始数字值:在默认情况下,每一项是用一个32位的整数来存储的,但如果需要,也可以改变存储大小(例如,在为Pocket PC之类的低内存设备编程时)。

另外,CTS要求枚举类型派生自基类System.Enum。

1.6.5 ; CTS委托类型委托(delegate)在.NET中等效于类型安全的C风格的函数指针。

它们的主要不同之处在于,.NET委托是派生自
System.MulticastDelegate的类,而不是一个简单地指向原始内存地址的指针。

在C#中,委托是使用关键字delegate来声明的:一个实体可以用委托向另一个实体传递调用,另外,委托也为.NET事件架构提供了基础。

1.6.6 ; CTS类型成员现在你已经看到了由CTS正式规定的各种类型,但还要认识到,大部分的类型可以含有任意数量的成员。

说得更正式一些,类型成员是集合{构造函数,终结器,静态构造函数,嵌套类型,运算符,方法,属性,索引器,字段,只读字段,常量,事件}中的元素之一。

CTS定义了各种可能与具体成员关联的"修饰语"。

例如,每个成员都有一个给定的可见性特征(如公共的、私有的和受保护的等)。

有些成员可能被声明成抽象的,以加强派生类的多态性,有些成员可声明为虚拟的,以定义一个封装(但可重写)的实现。

同样,绝大部分成员可设置成静态的(在类级别绑定)或者实例(在对象级别绑定)。

类型成员的构造会在以后的几章中介绍。

1.6.7 ; 内建的CTS数据类型CTS需要关注的最后一个方面,是它建立的一套定义明确的核心数据类型。

尽管不同的语言通常都有自己唯一的用于声明内建CTS数据类型的关键字,但是所有语言的关键字最终将解析成定义在mscorlib.dll程序集中的相同类型。

参考下表,它描述了如何在不同的.NET语言中表示关键的CTS数据类型。

表 ; 内建的CTS数据类型由于各种托管语言的关键字只是System命名空间中真实类型的简化符号,我们不需要担心数值数据的上溢或下溢,或是字符串和布尔型数据在内部是怎样跨不同语言进行表示的。

如下代码片段使用C#和,通过语言关键字和正式的CTS类型分别定义了32位数值变量。

;1.7 CLS我们知道
,不同的语言往往用不同的、语言特定的术语表达相同的程序构造,比如,在C#中使用加号(+)运算符表示字符串拼接,而在中却使用"&"符号。

即使两种不同的语言表达相同的编程惯用法(比如一个不返回值的函数),在表面看起来,语法也可能非常不同。

;正如你已经看到的,在.NET运行库看来这些较小的语法变化是微不足道的,因而不同的编译器(这里用到的是vbc.exe或csc.exe)将产生类似的CIL指令集。

然而语言也。

相关文档
最新文档