100162732.htm

来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 298 行 · 第 1/5 页

HTM
298
字号
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">下面的一个例子是有关区分大小写字母的。</span><span lang="EN-US">IL</span><span style="FONT-FAMILY: 宋体">是区分大小写的语言。使用这些语言的开发人员常常利用区分大小写所提供的灵活性来选择变量名。但</span><span lang="EN-US">VB.NET</span><span style="FONT-FAMILY: 宋体">是不区分大小写的语言。</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">就要指定</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">兼容代码不使用任何只根据大小写来区分的名称。因此,</span><span lang="EN-US">VB.NET</span><span style="FONT-FAMILY: 宋体">代码可以与</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">兼容代码一起使用。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这个例子说明了</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">的两种工作方式。首先是各个编译器的功能不必强大到支持</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">的所有功能,这将鼓励人们为其他面向</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">的编程语言开发编译器。第二,它提供如下保证:如果限制类只能使用</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">兼容的特性,就要保证用其他语言编写的代码可以使用这个类。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这种方法的优点是使用</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">兼容特性的限制只适用于公共和受保护的类成员和公共类。在类的私有实现方式中,可以编写非</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">代码,因为其他程序集</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">托管代码的单元,参见本章后面的内容</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">中的代码不能访问这部分代码。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这里不深入讨论</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">规范。在一般情况下,</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">对</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">代码的影响不会太大,因为</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">中的非</span><span lang="EN-US">CLS</span><span style="FONT-FAMILY: 宋体">兼容特性非常少。</span></p>
<h4 style="TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">垃圾收集</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">中进行内存管理,特别是它可以恢复正在运行中的应用程序需要的内存。到目前为止,</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">平台已经使用了两种技术来释放进程向系统动态请求的内存:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; TEXT-INDENT: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">完全以手工方式使应用程序代码完成这些工作</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; TEXT-INDENT: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">让对象维护引用计数。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">让应用程序代码负责释放内存是低级、高性能的语言使用的技术,例如</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">。这种技术很有效,且可以让资源在不需要时就释放</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">一般情况下</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">,但其最大的缺点是频繁出现错误。请求内存的代码还必须明确通知系统它什么时候不再需要该内存。但这是很容易被遗漏的,从而导致内存泄漏。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">尽管现代的开发环境提供了帮助检测内存泄漏的工具,但它们很难跟踪错误,因为直到内存已大量泄漏从而使</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">拒绝为进程提供资源时,它们才会发挥作用。从这层意义上说,由于对内存的需求,会使整个计算机变得相当慢。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">维护引用计数是</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">对象采用的一种技术,其方法是每个</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">组件都保留一个计数,记录客户机目前对它的引用数。当这个计数下降到</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体">时,组件就会删除自己,并释放相应的内存和资源。它带来的问题是仍需要客户机通知组件它们已经完成了内存的使用。只要有一个客户机没有这么做,对象就仍驻留在内存中。在某些方面,这是比</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">内存泄漏更为严重的问题,因为</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">对象可能存在于它自己的进程中,从来不会被系统删除</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">在</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">内存泄漏问题上,系统至少可以在进程中断时释放所有的内存</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">运行库采用的方法是垃圾收集器,这是一个程序,其目的是清理内存,方法是所有动态请求的内存都分配到堆上</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">这对所有的语言都一样,但在</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">中,</span><span lang="EN-US">CLR</span><span style="FONT-FAMILY: 宋体">维护它自己的托管堆,以供</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">应用程序使用</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">,当</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">检测到给定进程的托管堆已满,需要清理时,就调用垃圾收集器。垃圾收集器处理目前代码中的所有变量,检查对存储在托管堆上的对象的引用,确定哪些对象可以从代码中访问<span style="LETTER-SPACING: -0.5pt">&mdash;&mdash;</span></span><span style="LETTER-SPACING: -0.5pt"> </span><span style="FONT-FAMILY: 宋体">即哪些对象有引用。没有引用的对象就不能再从代码中访问,因而被删除。</span><span lang="EN-US">Java</span><span style="FONT-FAMILY: 宋体">就使用与此类似的垃圾收集器系统。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">之所以在</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">中使用垃圾收集器,是因为中间语言已用来处理进程。其规则要求,第一,不能引用已有的对象,除非复制已有的引用。第二,中间语言是类型安全的语言。在这里,其含义是如果存在对对象的任何引用,该引用中就有足够的信息来确定对象的类型。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">垃圾收集器机制不能和诸如非托管</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">这样的语言一起使用,因为</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">允许指针自由地转换数据类型。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">垃圾收集器的一个重要方面是它是不确定的。换言之,不能保证什么时候会调用垃圾收集器:</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">运行库决定需要它时,就可以调用它</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">除非明确调用垃圾收集器</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。但可以重写这个过程,在代码中调用垃圾收集器。</span></p>
<h4 style="TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">安全性</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">很好地补足了</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">提供的安全机制,因为它提供的安全机制是基于代码的安全性,而</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">仅提供了基于角色的安全性。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">基于角色的安全性建立在运行进程的账户的身份基础上,换言之,就是谁拥有和运行进程。另一方面,基于代码的安全性建立在代码实际执行的任务和代码的可信程度上。由于中间语言提供了强大的类型安全性,所以</span><span lang="EN-US">CLR</span><span style="FONT-FAMILY: 宋体">就可以在运行代码前检查它,以确定是否有需要的安全权限。</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">还提供了一种机制,可以在运行代码前指定代码需要什么安全权限。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">基于代码的安全性非常重要,原因是它降低了运行怀疑其出处的代码的风险</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">例如代码是从</span><span lang="EN-US">Internet</span><span style="FONT-FAMILY: 宋体">上下载来的</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。即使代码运行在管理员账户下,也有可能使用基于代码的安全性,来确定这段代码是否仍不能执行管理员账户一般允许执行的某些类型的操作,例如读写环境变量、读写注册表或访问</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">反射特性。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">安全问题详见本书后面的第</span><span lang="EN-US">14</span><span style="FONT-FAMILY: 宋体">章。</span></p>
<h4 style="TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">应用程序域</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">中的一个重要技术改进,它用于减少运行应用程序的系统开销,这些应用程序需要与其他程序分离开来,但同时还需要彼此通信。典型的例子是</span><span lang="EN-US">Web</span><span style="FONT-FAMILY: 宋体">服务器应用程序,它需要同时响应许多浏览器请求。因此,要有许多组件实例同时响应这些同时运行的请求。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">没有开发出来前,可以让这些实例共享同一个进程,但此时一个运行的实例就有可能导致整个网站的崩溃;也可以把这些实例孤立在不同的进程中,但这样做会增加相关性能的系统开销。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">到现在为止,孤立代码的惟一方式是通过进程来实现的。在运行一个新的应用程序时,它会在一个进程环境内运行。</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">通过地址空间把进程分隔开来。这样,每个进程有</span><span lang="EN-US">4GB</span><span style="FONT-FAMILY: 宋体">的虚拟内存来存储其数据和可执行代码</span><span lang="EN-US">(4GB</span><span style="FONT-FAMILY: 宋体">对应于</span><span lang="EN-US">32</span><span style="FONT-FAMILY: 宋体">位系统,</span><span lang="EN-US">64</span><span style="FONT-FAMILY: 宋体">位系统要用更多的内存</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">利用额外的间接方式把这些虚拟内存映射到物理内存或磁盘空间的一个特殊区域中,每个进程都会有不同的映射,虚拟地址空间块映射的物理内存之间不能有重叠,这种情况如图</span><span lang="EN-US">1-2</span><span style="FONT-FAMILY: 宋体">所示。</span></p>
<p align="center"><span lang="EN-US"><img height="241" alt="" width="235" src="01/image002.gif" /></span></p>
<p style="MARGIN-BOTTOM: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 1-2</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在一般情况下,任何进程都只能通过指定虚拟内存中的一个地址来访问内存<span style="LETTER-SPACING: -0.5pt">&mdash;&mdash;</span>即进程不能直接访问物理内存,因此一个进程不可能访问分配给另一个进程的内存。这样就可以确保任何执行出错的代码不会损害其地址空间以外的数据</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">注意在</span><span lang="EN-US">Windows 9x</span><span style="FONT-FAMILY: 宋体">上,这些保护措施不像在</span><span lang="EN-US">NT/2000/XP/2003</span><span style="FONT-FAMILY: 宋体">上那样强大,所以理论上存在应用程序因写入不对应的内存而导致</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">崩溃的可能性</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">进程不仅是运行代码的实例相互隔离的一种方式,在</span><span lang="EN-US">Windows NT/2000/XP/2003</span><span style="FONT-FAMILY: 宋体">系统上,它们还可以构成分配了安全权限和许可的单元。每个进程都有自己的安全标识,明确地表示</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">允许该进程可以执行的操作。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">进程对确保安全有很大的帮助,而它们的一大缺点是性能。许多进程常常在一起工作,因此需要相互通信。一个常见的例子是进程调用一个</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">组件,而该</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">组件是可执行的,因此需要在它自己的进程上运行。在</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">中使用代理时也会发生类似的情况。因为进程不能共享任何内存,所以必须使用一个复杂的编组过程在进程之间复制数据。这对性能有非常大的影响。如果需要使组件一起工作,但不希望性能有损失,惟一的方法是使用基于</span><span lang="EN-US">DLL</span><span style="FONT-FAMILY: 宋体">的组件,让所有的组件在同一个地址空间中运行<span style="LETTER-SPACING: -0.5pt">&mdash;&mdash;</span></span><span style="LETTER-SPACING: -0.5pt"> </span><span style="FONT-FAMILY: 宋体">其相关的风险是执行出错的组件会影响其他组件。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">应用程序域是分离组件的一种方式,它不会导致因在进程之间传送数据而产生性能问题。其方法是把任何一个进程分解到多个应用程序域中,每个应用程序域大致对应一个应用程序,执行的每个线程都运行在一个具体的应用程序域中,如图</span><span lang="EN-US">1-3</span><span style="FONT-FAMILY: 宋体">所示。</span></p>
<p align="center"><span lang="EN-US"><img height="184" alt="" width="165" src="01/image003.gif" /></span></p>
<p style="MARGIN-BOTTOM: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 1-3</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">如果不同的可执行文件都运行在同一个进程空间中,显然它们就能轻松地共享数据,因为理论上它们可以直接访问彼此的数据。虽然在理论上这是可以实现的,但是</span><span lang="EN-US">CLR</span><span style="FONT-FAMILY: 宋体">会检查每个正在运行的应用程序的代码,以确保这些代码不偏离它自己的数据区域,保证不发生直接访问其他进程的数据的情况。这初看起来是不可能的,如何告诉程序要做什么工作,而又不真正运</span><span lang="EN-US">&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 宋体">行它?</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">实际上,这么做通常是可能的,因为中间语言拥有强大的类型安全功能。在大多数情况下,除非代码明确使用不安全的特性,例如指针,否则它使用的数据类型可以确保内存不会被错误地访问。例如,</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">数组类型执行边界检查,以禁止执行超出边界的数组操作。如果运行的应用程序的确需要与运行在不同应用程序域中的其他应用程序通信或共享数据,就必须调用</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">的远程服务。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">被验证不能访问超出其应用程序域的数据</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">而不是通过明确的远程机制</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">的代码就是内存类型安全的代码,这种代码与运行在同一个进程中但应用程序域不同的类型安全代码一起运行是安全的。</span></p>
<h3 style="MARGIN: 8.15pt 0cm"><span lang="EN-US">1.3.4</span><span lang="EN-US"> &nbsp;</span><span style="FONT-FAMILY: 黑体">通过异常处理错误</span></h3>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">可以根据异常使用相同的机制处理错误情况,这与</span><span lang="EN-US">Java</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">是一样的。</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">开发人员应注意到,由于</span><span lang="EN-US">IL</span><span style="FONT-FAMILY: 宋体">有非常强大的类型系统,所以在</span><span lang="EN-US">IL</span><span style="FONT-FAMILY: 宋体">中以</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">的方式使用异常不会带来相关的性能问题。另外,</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">也支持</span><span lang="EN-US">finally</span><span style="FONT-FAMILY: 宋体">块,这是许多</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">开发人员长久以来的愿望。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">第</span><span lang="EN-US">11</span><span style="FONT-FAMILY: 宋体">章会详细讨论异常。简要地说,代码的某些领域被看作是异常处理程序例程,每个例程都能处理某种特殊的错误情况</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">例如,找不到文件,或拒绝执行某些操作的许可</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。这些条件可以定义得很宽或很窄。异常结构确保在发生错误情况时,执行进程立即跳到异常处理程序例程上,处理有问题的错误情况。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">异常处理的结构还提供了一种方便的方式,当对象包含错误情况的准确信息时,该对象就可以传送给错误处理例程。这个对象包括给用户提供的相应信息和在代码的什么地方检测到错误的确切信息。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">大多数异常处理结构,包括异常发生时的程序流控制,都是由高级语言处理的,例如</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">VB.NET</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">,任何中间语言命令都不支持它。例如,</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">使用</span><span lang="EN-US">try{}</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">catch{}</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US"> finally{}</span><span style="FONT-FAMILY: 宋体">代码块来处理它,详见第</span><span lang="EN-US">11</span><span style="FONT-FAMILY: 宋体">章。</span></p>
<p class="MsoNormal"><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">提供了一种基础结构,让面向</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">的编译器支持异常处理。特别是它提供了一组</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">类来表示异常,语言的互操作性则允许抛出被错误处理代码解释的异常对象,无论错误处理代码使用什么语言编写都是这样。语言的无关性没有体现在</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">Java</span><span style="FONT-FAMILY: 宋体">的异常处理实现中,但在</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">的错误处理机制中有一定限度的体现。</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">的错误处理机制包括从方法中返回错误代码以及传递错误对象。在不同语言中,错误的处理是一致的,这是多语言开发的重要一环。</span></p>
<h3 style="MARGIN: 8.15pt 0cm"><span lang="EN-US">1.3.5</span><span lang="EN-US"> &nbsp;</span><span style="FONT-FAMILY: 黑体">特性</span><span style="FONT-FAMILY: 黑体">的使用</span></h3>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">是使用</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">编写</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">组件的开发人员很熟悉的一个功能</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">使用</span><span lang="EN-US">Microsoft</span><span style="FONT-FAMILY: 宋体">的</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">接口定义语言</span><span lang="EN-US">(IDL))</span><span style="FONT-FAMILY: 宋体">。特性最初是为了在程序中提供与某些项目相关的外部信息,以供编译器使用。</span></p>
<p class="MsoNormal"><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">支持特性,因此现在</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">VB.NET</span><span style="FONT-FAMILY: 宋体">也支持特性。但在</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">中,对特性的革新是建立了一个机制,通过该机制可以在源代码中定义自己的特性。这些用户定义的特性将和对应数据类型或方法的元数据放在一起,这对于文档说明书十分有用,它们和反射技术一起使用,以根据特性执行编程任务。另外,与</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">的语言无关性的基本原理一样,特性也可以在一种语言的源代码中定义,而被用另一种语言编写的代码读取。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">本书的第</span><span lang="EN-US">10</span><span style="FONT-FAMILY: 宋体">章详细介绍了特性。</span></p></div>
                <!-- page -->
                <div class="page" style="text-align: center">
                    <a href="100162731.htm">上一页</a>&nbsp;&nbsp;&nbsp;<a href="index.html">首页</a>&nbsp;&nbsp;&nbsp;<a href="100162733.htm">下一页</a>
                </div>
                <div style="margin: 0px auto; width: 700px; border: solid 1px #0b5f98;">
                    <div style="float: left; width: 16px; background-color: #0b5f98; color: White; padding: 1px;">
                        图书导读
                    </div>
                    <div style="float: right; width: 670px; text-align: left; line-height: 16pt; padding-left: 2px">
                        <!--导读-->
                        <h1 id="divCurrentNode2" style="color: #b83507; width: 100%; text-align: left; font-size: 12px; padding-left: 2px">当前章节:<a href='100162732.htm'><font color='red'>1.3  中间语言</font></a></h1>
                        <div id="divRealteNod2" style="padding-left: 2px">
                        <div style='float:left;width:49%'>·<a href='100162730.htm'>1.1  C#与.NET的关

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?