<html xmlns="http://www.w3.org/1999/xhtml"><head><meta charset="utf-8"><meta name="generator" content="pdf2htmlEX"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><link rel="stylesheet" href="https://csdnimg.cn/release/download_crawler_static/css/base.min.css"><link rel="stylesheet" href="https://csdnimg.cn/release/download_crawler_static/css/fancy.min.css"><link rel="stylesheet" href="https://csdnimg.cn/release/download_crawler_static/2366853/raw.css"><script src="https://csdnimg.cn/release/download_crawler_static/js/compatibility.min.js"></script><script src="https://csdnimg.cn/release/download_crawler_static/js/pdf2htmlEX.min.js"></script><script>try{pdf2htmlEX.defaultViewer = new pdf2htmlEX.Viewer({});}catch(e){}</script><title></title></head><body><div id="sidebar" style="display: none"><div id="outline"></div></div><div id="pf1" class="pf w0 h0" data-page-no="1"><div class="pc pc1 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://csdnimg.cn/release/download_crawler_static/2366853/bg1.jpg"><div class="t m0 x1 h2 y1 ff1 fs0 fc0 sc0 ls0 ws0"><span class="fc1 sc0"> </span></div><div class="t m0 x2 h2 y2 ff1 fs0 fc0 sc0 ls0 ws0"> </div><div class="t m0 x3 h3 y3 ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x4 h3 y4 ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x3 h3 y5 ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x4 h3 y6 ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x5 h4 y7 ff2 fs2 fc0 sc0 ls1 ws0">.NET<span class="_ _0"> </span>体系结构 </div><div class="t m0 x3 h3 y8 ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x3 h3 y9 ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x3 h3 ya ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x3 h3 yb ff1 fs1 fc0 sc0 ls0 ws0"> </div><div class="t m0 x4 h5 yc ff2 fs1 fc0 sc0 ls2 ws0">我们不能孤立地使用<span class="_ _1"> </span><span class="ff1 ls3">C#</span>语言,而必须和<span class="ff1 ls4 ws1">.N<span class="_ _2"></span>ET<span class="_ _2"></span> Fram<span class="_ _2"></span>ework<span class="_ _1"> </span><span class="ff2 ls2 ws0">一起考虑。<span class="ff1 ls3">C#</span>编译器专门用</span></span></div><div class="t m0 x6 h5 yd ff2 fs1 fc0 sc0 ls0 ws0">于<span class="ff1 ls5">.NET</span>,这表示用<span class="_ _3"> </span><span class="ff1 ls3">C#</span><span class="ls2">编写的所有代码总是在<span class="ff1 ls6 ws2">.N<span class="_ _2"></span>ET F<span class="_ _2"></span>ramew<span class="_ _2"></span>ork<span class="_"> </span><span class="ff2 ls2 ws0">中运行。对于<span class="_ _1"> </span><span class="ff1 ls3">C#</span>语言来说,</span></span></span></div><div class="t m0 x6 h5 ye ff2 fs1 fc0 sc0 ls2 ws0">可以得出两个重要的<span class="_ _2"></span>结论:<span class="ff1 ls0"> </span></div><div class="t m0 x4 h6 yf ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff1 ls3">C#<span class="ff2 ls2">的结构和方法论反映了</span><span class="ls5">.NET<span class="_"> </span></span></span><span class="ff2">基础方法论。<span class="ff1"> </span></span></span></div><div class="t m0 x4 h6 y10 ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">在许多情况下,<span class="ff1 ls3">C#</span>的特定语言功<span class="_ _2"></span>能取决于<span class="ff1 ls7">.NE<span class="_ _2"></span>T<span class="_"> </span><span class="ff2 ls2">的功能,或依<span class="_ _2"></span>赖于<span class="ff1 ls7">.NE<span class="_ _2"></span>T<span class="_"> </span><span class="ff2 ls0">基类。<span class="ff1"> </span></span></span></span></span></span></span></div><div class="t m0 x4 h5 y11 ff2 fs1 fc0 sc0 ls2 ws0">由于这种依赖性,在<span class="_ _2"></span>开始使用<span class="_ _5"> </span><span class="ff1 ls3">C#</span>编程前,了解<span class="ff1 ls7">.NE<span class="_ _2"></span>T<span class="_ _5"> </span><span class="ff2 ls2">的结构和方法论就非常重要了,</span></span></div><div class="t m0 x6 h5 y12 ff2 fs1 fc0 sc0 ls2 ws0">这就是本章的目的。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y13 ff2 fs1 fc0 sc0 ls2 ws0">本章首先了解在<span class="ff1 ls8">.N<span class="_ _2"></span>ET<span class="_ _6"> </span><span class="ff2 ls2">编译和运行所有的代码</span><span class="ls0">(<span class="ff2 ls2">包括<span class="_ _6"> </span></span><span class="ls3">C#)<span class="ff2 ls2">时通常会出现<span class="_ _2"></span>什么情况。对这</span></span></span></span></div><div class="t m0 x6 h5 y14 ff2 fs1 fc0 sc0 ls2 ws0">些内容进行概述之后<span class="_ _2"></span>,就要详细阐述<span class="_ _1"> </span><span class="ff1 ls9">Microsoft<span class="_"> </span></span>中间语言<span class="ff1 lsa ws3">(Microsoft Intermediate Language</span><span class="ls0">,</span></div><div class="t m0 x6 h5 y15 ff1 fs1 fc0 sc0 lsb ws0">MSIL<span class="_"> </span><span class="ff2 ls2">或简称为<span class="_ _1"> </span></span><span class="lsc">IL<span class="_ _7"></span>)<span class="ff2 ls2">,<span class="_ _8"></span>所有编译好的代码都要使<span class="_ _2"></span>用这种语言。<span class="_ _8"></span>本章特别要介<span class="_ _2"></span>绍<span class="_ _1"> </span><span class="ff1 lsc">IL<span class="_ _7"></span></span>、<span class="_ _8"></span>通用类型</span></span></div><div class="t m0 x6 h5 y16 ff2 fs1 fc0 sc0 ls0 ws0">系统<span class="ff1 lsd ws4">(Common T<span class="_ _9"></span>ype System<span class="_ _2"></span><span class="ff2 ls0 ws0">,<span class="ff1 lse">CTS)</span><span class="ls2">及公共语言规范<span class="ff1 lsf ws5">(Common Language Specification<span class="_ _2"></span><span class="ff2 ls0 ws0">,<span class="ff1 ls10">CLS)</span></span></span></span></span></span></div><div class="t m0 x6 h5 y17 ff2 fs1 fc0 sc0 ls2 ws0">如何提供<span class="ff1 ls8">.NET<span class="_ _1"> </span></span>语言之间的互操作性。<span class="_ _2"></span>最后解释各种语言如何<span class="_ _2"></span>使用<span class="ff1 ls7">.NET</span><span class="ls0">,包括<span class="_ _1"> </span><span class="ff1 ls11 ws6">V<span class="_ _9"></span>isual Basic</span></span></div><div class="t m0 x6 h5 y18 ff2 fs1 fc0 sc0 ls0 ws0">和<span class="_ _1"> </span><span class="ff1 ls12">C++</span>。<span class="ff1"> </span></div><div class="t m0 x4 h5 y19 ff2 fs1 fc0 sc0 ls2 ws0">之后,我们将介绍<span class="ff1 ls7">.N<span class="_ _2"></span>ET<span class="_ _5"> </span><span class="ff2 ls2">的其他特<span class="_ _2"></span>性,包括程序集、命名<span class="_ _2"></span>空间和<span class="ff1 ls7">.NE<span class="_ _2"></span>T<span class="_ _5"> </span><span class="ff2 ls2">基类。最后本章</span></span></span></span></div><div class="t m0 x6 h5 y1a ff2 fs1 fc0 sc0 ls2 ws0">简要探讨一下<span class="_ _1"> </span><span class="ff1 ls3">C#</span>开发人员可以创建的应用程序类型。</div><div class="t m0 x7 h7 y1b ff1 fs3 fc0 sc0 ls0 ws0"> </div><div class="t m0 x6 h8 y1c ff5 fs4 fc0 sc0 ls13 ws7">1.1 C#<span class="ff6 sc1 ls0 ws0">与</span><span class="ls14 ws0">.NET<span class="_"> </span><span class="ff6 sc1 ls15">的关系</span><span class="ls0"> </span></span></div><div class="t m0 x4 h5 y1d ff1 fs1 fc0 sc0 ls3 ws0">C#<span class="ff2 ls2">是一种相当新的编程语言,<span class="_ _2"></span><span class="ff1 ls3">C#<span class="ff2 ls2">的重要性体现在以下两个方<span class="_ _2"></span>面:<span class="ff1 ls0"> </span></span></span></span></div><div class="t m0 x4 h6 y1e ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">它是专门为与<span class="_ _1"> </span><span class="ff1 ls9">Microsoft<span class="_"> </span></span><span class="ls0">的<span class="ff1 ls16 ws8">.NET Fra<span class="_ _7"></span>mework<span class="_"> </span></span></span>一起使用而设计的。<span class="ff1 ls17 ws9">(<span class="_ _2"></span>.NET Fr<span class="_ _2"></span>amew<span class="_ _2"></span>ork</span></span></span></div><div class="t m0 x8 h5 y1f ff2 fs1 fc0 sc0 ls2 ws0">是一个功能非常丰富<span class="_ _2"></span>的平台,可开发、部署和执<span class="_ _2"></span>行分布式应用程序<span class="ff1 ls0">)<span class="ff2">。</span> </span></div><div class="t m0 x4 h6 y20 ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">它是一种基于现代面<span class="_ _2"></span>向对象设计方法的语言,在<span class="_ _2"></span>设计它时,<span class="ff1 ls9">Microsoft<span class="_"> </span></span>还吸取了其</span></span></div><div class="t m0 x8 h5 y21 ff2 fs1 fc0 sc0 ls2 ws0">他类似语言的经验<span class="_ _2"></span>,<span class="_ _9"></span>这些语言是近<span class="_ _1"> </span><span class="ff1 ls18">20<span class="_"> </span></span>年来面向对象规则得到广<span class="_ _2"></span>泛应用后才开发出</div><div class="t m0 x8 h5 y22 ff2 fs1 fc0 sc0 ls0 ws0">来的。<span class="ff1"> </span></div><div class="t m0 x4 h5 y23 ff2 fs1 fc0 sc0 ls2 ws0">有一个很重要的问题<span class="_ _2"></span>要弄明白:<span class="_ _a"></span><span class="ff1 ls3">C#<span class="ff2 ls2">就其本身而言只是一种语言,<span class="_ _8"></span>尽管它是用于生成面</span></span></div><div class="t m0 x9 h9 y24 ff6 fs5 fc0 sc0 ls19 ws0">第 章 </div><div class="t m0 xa ha y25 ff7 fs6 fc0 sc0 ls0 ws0">1</div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div></body></html>
<div id="pf2" class="pf w0 h0" data-page-no="2"><div class="pc pc2 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://csdnimg.cn/release/download_crawler_static/2366853/bg2.jpg"><div class="t m0 x6 h6 y26 ff6 fs0 fc0 sc0 ls0 ws0">第Ⅰ部分<span class="ff4 ls1a"> C<span class="_ _b"></span>#<span class="_ _b"></span> <span class="ff6 ls0">语<span class="ff4"> <span class="_ _c"> </span></span>言<span class="ff4 fs1"> </span></span></span></div><div class="t m0 x2 h2 y2 ff1 fs0 fc0 sc0 ls0 ws0"> </div><div class="t m0 xb hb y27 ff5 fs1 fc0 sc0 ls0 ws0">4</div><div class="t m0 x6 h5 y3 ff2 fs1 fc0 sc0 ls0 ws0">向<span class="ff1 ls5">.NET<span class="_"> </span></span><span class="ls2">环境的代码,但它本身不<span class="_ _2"></span>是<span class="ff1 ls7">.NET<span class="_ _1"> </span></span>的一部分。<span class="ff1 ls8">.N<span class="_ _2"></span>ET<span class="_"> </span><span class="ff2 ls2">支持的一些特性<span class="_ _2"></span>,<span class="ff1 ls3">C#</span>并不支持。</span></span></span></div><div class="t m0 x6 h5 y4 ff2 fs1 fc0 sc0 ls0 ws0">而<span class="_ _1"> </span><span class="ff1 ls3">C#</span><span class="ls2">语言支持的另一些特性,<span class="ff1 ls7">.NET<span class="_"> </span></span>却<span class="_ _2"></span>不支持<span class="ff1 ls0">(</span>例如运算符重载<span class="ff1 ls0">)<span class="ff2">!</span> </span></span></div><div class="t m0 x4 h5 y5 ff2 fs1 fc0 sc0 ls2 ws0">但是,因为<span class="_ _1"> </span><span class="ff1 ls3">C#</span>语言是和<span class="ff1 ls7">.NET<span class="_"> </span></span>一<span class="_ _2"></span>起使用的,所以如果要使<span class="_ _2"></span>用<span class="_ _1"> </span><span class="ff1 ls3">C#</span>高效地开发应用程序,</div><div class="t m0 x6 h5 y6 ff2 fs1 fc0 sc0 ls0 ws0">理解<span class="_ _3"> </span><span class="ff1 ls1b">Fram<span class="_ _2"></span>ework<span class="_"> </span><span class="ff2 ls2">就非常重要<span class="_ _2"></span>,所以本章将介绍<span class="ff1 ls8">.N<span class="_ _2"></span>ET<span class="_"> </span><span class="ff2 ls2">的内涵。<span class="_ _2"></span><span class="ff1 ls0"> </span></span></span></span></span></div><div class="t m0 x6 h8 y28 ff5 fs4 fc0 sc0 ls13 ws7">1.2 <span class="ff6 sc1 ls1c ws0">公共语言运行库</span><span class="ls0 ws0"> </span></div><div class="t m0 x4 h5 y29 ff1 fs1 fc0 sc0 ls1d wsa">.NET Framework<span class="_"> </span><span class="ff2 ls1e ws0">的核心是其运行库的执行<span class="_ _7"></span>环境,称为公共语言运行库<span class="ff1 ls1f">(C<span class="_ _7"></span>LR<span class="_ _7"></span>)</span><span class="ls0">或<span class="_ _7"></span><span class="ff1 ls20">.NET</span></span></span></div><div class="t m0 x6 h5 y2a ff2 fs1 fc0 sc0 ls21 ws0">运行库。通常将在<span class="_ _3"> </span><span class="ff1 ls22">CLR<span class="_"> </span></span>的控制下运行的代码称为托管代码<span class="ff1 ls23 wsb">(man<span class="_ _7"></span>aged code)</span><span class="ls0">。<span class="_ _d"></span><span class="ff1"> </span></span></div><div class="t m0 x4 h5 y2b ff2 fs1 fc0 sc0 ls0 ws0">但是,<span class="_ _e"></span>在<span class="_ _c"> </span><span class="ff1 ls11">CLR<span class="_ _f"> </span></span><span class="ls2">执行编写好的源代码<span class="_ _2"></span>之前,<span class="_ _e"></span>需要编译它<span class="_ _2"></span>们<span class="ff1 ls0">(<span class="ff2">在<span class="_ _f"> </span></span><span class="ls3">C#</span></span>中或其他语言中<span class="ff1 ls0">)<span class="ff2">。<span class="_ _e"></span>在<span class="ff1 ls8">.NET</span></span></span></span></div><div class="t m0 x6 h5 y2c ff2 fs1 fc0 sc0 ls2 ws0">中,编译分为两个阶<span class="_ _2"></span>段:<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y2d ff1 fs1 fc0 sc0 ls24 ws0">(1) <span class="_"> </span><span class="ff2 ls2">把源代码编译为<span class="_ _1"> </span></span><span class="ls25">Microsoft<span class="_ _1"> </span><span class="ff2 ls21">中间语言</span><span class="ls1f">(I<span class="_ _7"></span>L)<span class="ff2 ls0">。<span class="ff1"> </span></span></span></span></div><div class="t m0 x4 h5 y2e ff1 fs1 fc0 sc0 ls26 ws0">(2)<span class="ff2 ls0"> </span><span class="ls11">CLR<span class="_"> </span><span class="ff2 ls0">把<span class="_ _3"> </span></span><span class="ls1f">IL<span class="_"> </span><span class="ff2 ls2">编译为平台<span class="_ _2"></span>专用的代码。<span class="ff1 ls0"> </span></span></span></span></div><div class="t m0 x4 h5 y2f ff2 fs1 fc0 sc0 ls2 ws0">这个两阶段的编译过<span class="_ _2"></span>程非常重要,<span class="_ _10"></span>因为<span class="_ _1"> </span><span class="ff1 ls27">Microso<span class="_ _7"></span>ft<span class="_"> </span></span><span class="ls21">中间语言<span class="ff1 ls0">(</span>托管代码<span class="ff1 ls0">)<span class="_ _7"></span></span><span class="ls28">是提供<span class="ff1 ls20">.NET<span class="_"> </span></span><span class="ls0">的</span></span></span></div><div class="t m0 x6 h5 y30 ff2 fs1 fc0 sc0 ls21 ws0">许多优点的关键。<span class="ff1 ls0"> </span></div><div class="t m0 x6 hc y31 ff6 fs7 fc0 sc0 ls29 ws0">托管代码的优点<span class="ff4 ls0"> </span></div><div class="t m0 xc h5 y32 ff1 fs1 fc0 sc0 ls2a ws0">Micros<span class="_ _2"></span>oft<span class="_ _1"> </span><span class="ff2 ls2">中间语言与<span class="_ _c"> </span></span><span class="lsf">Java<span class="_"> </span><span class="ff2 ls2">字节代码共享一种理<span class="_ _2"></span>念:<span class="_ _e"></span>它们都是低级<span class="_ _2"></span>语言,<span class="_ _e"></span><span class="ls0">语法很简单<span class="ff1">(</span>使</span></span></span></div><div class="t m0 x6 h5 y33 ff2 fs1 fc0 sc0 ls2 ws0">用数字代码,<span class="_ _8"></span>而不是文本代码<span class="ff1 ls0">)</span>,<span class="_ _a"></span>可以非常快速地转换为内部机器码。<span class="_ _a"></span>对于代码来说,<span class="_ _8"></span>这种</div><div class="t m0 x6 h5 y34 ff2 fs1 fc0 sc0 ls2 ws0">精心设计的通用语法<span class="_ _2"></span>,有很重要的优点。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h6 y35 ff4 fs1 fc0 sc0 ls2b ws0">1. <span class="_ _1"> </span><span class="ff6 ls2">平台无关性</span><span class="ls0"> </span></div><div class="t m0 x4 h5 y36 ff2 fs1 fc0 sc0 ls2 ws0">首先,这意味着包含<span class="_ _2"></span>字节代码指令的同一文件可<span class="_ _2"></span>以放在任一平台中,运<span class="_ _2"></span>行时编译过程</div><div class="t m0 x6 h5 y37 ff2 fs1 fc0 sc0 ls2 ws0">的最后阶段可以很容<span class="_ _2"></span>易完成,这样代码就可以运<span class="_ _2"></span>行在特定的平台上。换<span class="_ _2"></span>言之,编译为中间</div><div class="t m0 x6 h5 y38 ff2 fs1 fc0 sc0 ls2 ws0">语言就可以获得<span class="ff1 ls8">.N<span class="_ _2"></span>ET<span class="_"> </span><span class="ff2 ls2">平台<span class="_ _2"></span>无关性,这与编译为<span class="_ _1"> </span><span class="ff1 ls2c">Java<span class="_"> </span></span>字节代码就会得到<span class="_ _1"> </span><span class="ff1 ls26">Java<span class="_"> </span></span>平台无关性是</span></span></div><div class="t m0 x6 h5 y39 ff2 fs1 fc0 sc0 ls2 ws0">一样的。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y3a ff2 fs1 fc0 sc0 ls2d ws0">注意<span class="ff1 ls5">.NET<span class="_ _11"> </span></span>的平台无关性目前只是一种可能,因为<span class="_ _2"></span>在编写本书时,<span class="ff1 ls8">.NET<span class="_ _12"> </span></span>只能用于</div><div class="t m0 x6 h5 y3b ff1 fs1 fc0 sc0 lsd ws0">W<span class="_ _9"></span>indows<span class="_"> </span><span class="ff2 ls2">平台,<span class="_ _a"></span>但人们正在积极准备,<span class="_ _a"></span>使它可以用于其他平<span class="_ _2"></span>台<span class="ff1 ls0">(<span class="ff2">参见<span class="_ _3"> </span></span><span class="lsd">Mono<span class="_"> </span></span></span>项目,<span class="_ _8"></span>它用于实</span></div><div class="t m0 x6 h5 y3c ff2 fs1 fc0 sc0 ls0 ws0">现<span class="ff1 ls5">.NET<span class="_"> </span></span><span class="ls2">的开放源代码,参见<span class="_ _1"> </span><span class="ff1 ls2e">http://www<span class="_ _9"></span>.go-mono.com/)<span class="ff2 ls0">。<span class="ff1"> </span></span></span></span></div><div class="t m0 x4 h6 y3d ff4 fs1 fc0 sc0 ls2b ws0">2. <span class="_ _1"> </span><span class="ff6 ls2">提高性能</span><span class="ls0"> </span></div><div class="t m0 x4 h5 y3e ff2 fs1 fc0 sc0 ls0 ws0">前面把<span class="_ _3"> </span><span class="ff1 lsc">IL<span class="_"> </span></span>和<span class="_ _3"> </span><span class="ff1 lsf">Java<span class="_"> </span></span><span class="ls2">做了比较,<span class="_ _13"></span>实际上,<span class="_ _13"></span><span class="ff1 lsc">IL<span class="_ _3"> </span><span class="ff2 ls0">比<span class="_ _3"> </span></span><span class="lsf">Java<span class="_"> </span><span class="ff2 ls2">字节代码的作用<span class="_ _2"></span>还要大。<span class="_ _13"></span><span class="ff1 ls1f">IL<span class="_"> </span><span class="ff2 ls2">总是即时</span></span></span></span></span></span></div><div class="t m0 x6 h5 y3f ff2 fs1 fc0 sc0 ls0 ws0">编译的<span class="ff1">(</span><span class="ls2">称为<span class="_ _5"> </span><span class="ff1 ls2f">JIT<span class="_ _3"> </span></span></span>编译<span class="_ _7"></span><span class="ff1">)</span><span class="ls2">,而<span class="_ _3"> </span><span class="ff1 lsf">Java<span class="_ _5"> </span></span>字节代码常常是解释性的<span class="_ _2"></span>,<span class="ff1 ls2c">Java<span class="_ _3"> </span></span><span class="ls0">的一<span class="_ _7"></span>个缺点是,在运行应</span></span></div><div class="t m0 x6 h5 y40 ff2 fs1 fc0 sc0 ls2 ws0">用程序时,把<span class="_ _14"> </span><span class="ff1 lsf">Java<span class="_ _14"> </span></span>字节代码转换为内部可执行代码的过程会<span class="_ _2"></span>导致性能的损失<span class="ff1 ls0">(</span>但在最近,</div><div class="t m0 x6 h5 y41 ff1 fs1 fc0 sc0 lsf ws0">Java<span class="_"> </span><span class="ff2 ls2">在某些平台上能进行<span class="_ _1"> </span></span><span class="ls30">JIT<span class="_"> </span><span class="ff2 ls2">编译</span><span class="ls0">)<span class="ff2">。</span> </span></span></div><div class="t m0 x4 h5 y42 ff1 fs1 fc0 sc0 ls2f ws0">JIT<span class="_"> </span><span class="ff2 ls2">编译器并不是把整个应用程序一次<span class="_ _2"></span>编译完<span class="ff1 ls0">(</span>这样会有很长的启动时<span class="_ _2"></span>间<span class="ff1 ls0">)<span class="ff2">,<span class="_ _15"></span><span class="ls2">而是只编译</span></span></span></span></div><div class="t m0 x6 h5 y43 ff2 fs1 fc0 sc0 ls1e ws0">它调用的那部分代码<span class="ff1 ls0">(</span>这是其名<span class="_ _7"></span>称由来<span class="ff1 ls0">)</span>。代码编译过一次后,得到的内<span class="_ _7"></span>部可执行代码就存</div><div class="t m0 x6 h5 y44 ff2 fs1 fc0 sc0 ls2 ws0">储起来,<span class="_ _b"></span>直到退出该应用程序为止,<span class="_ _b"></span>这样在下次运行这部分代码时,<span class="_ _b"></span>就不需要重新编译了。</div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>
<div id="pf3" class="pf w0 h0" data-page-no="3"><div class="pc pc3 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://csdnimg.cn/release/download_crawler_static/2366853/bg3.jpg"><div class="t m0 xd hd y26 ff6 fs0 fc0 sc0 ls0 ws0">第<span class="_ _c"> </span><span class="ff4">1<span class="_"> </span></span>章<span class="ff4 ls1a"> .<span class="_ _b"></span>N<span class="_ _b"></span>E<span class="_ _b"></span>T<span class="_ _7"></span><span class="ff6 ls0">体系结构<span class="ff4"> </span></span></span></div><div class="t m0 x2 h2 y45 ff1 fs0 fc0 sc0 ls0 ws0"> </div><div class="t m0 xe hb y46 ff5 fs1 fc0 sc0 ls31 ws0">5 </div><div class="t m0 x6 h5 y3 ff1 fs1 fc0 sc0 ls11 ws0">Microsoft<span class="_"> </span><span class="ff2 ls2">认为这个过程要比一开始就<span class="_ _2"></span>编译整个应用程序代码的效率<span class="_ _2"></span>高得多,<span class="_ _b"></span>因为任何应用</span></div><div class="t m0 x6 h5 y4 ff2 fs1 fc0 sc0 ls2 ws0">程序的大部分代码实<span class="_ _2"></span>际上并不是在每次运行过程<span class="_ _2"></span>中都执行。使用<span class="_ _5"> </span><span class="ff1 ls30">JIT<span class="_ _5"> </span></span>编译器,从来都不会</div><div class="t m0 x6 h5 y5 ff2 fs1 fc0 sc0 ls2 ws0">编译这种代码。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y6 ff2 fs1 fc0 sc0 ls2 ws0">这解释了为什么托管<span class="_ _1"> </span><span class="ff1 lsc">IL<span class="_"> </span></span>代码的执行几乎和内部机器代码<span class="_ _2"></span>的执行速度一样快,<span class="_ _16"></span>但是并没</div><div class="t m0 x6 h5 y47 ff2 fs1 fc0 sc0 ls2 ws0">有说明为什么<span class="_ _1"> </span><span class="ff1 ls9">Microsoft<span class="_"> </span></span>认为这会提高性能。<span class="_ _16"></span>其原因是编译过程的最后一部分是在运行<span class="_ _2"></span>时进</div><div class="t m0 x6 h5 y48 ff2 fs1 fc0 sc0 ls2 ws0">行的,<span class="ff1 ls2f">JIT<span class="_ _12"> </span></span>编译器确切地知道程序运行在什么<span class="_ _7"></span>类型的处理器上,可以利用该<span class="_ _7"></span>处理器提供的</div><div class="t m0 x6 h5 y49 ff2 fs1 fc0 sc0 ls2 ws0">任何特性或特定的机<span class="_ _2"></span>器代码指令来优化最后的可<span class="_ _2"></span>执行代码。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y4a ff2 fs1 fc0 sc0 ls2 ws0">传统的编译器会优化<span class="_ _2"></span>代码,但它们的优化过程是<span class="_ _2"></span>独立于代码所运行的特<span class="_ _2"></span>定处理器的。</div><div class="t m0 x6 h5 y4b ff2 fs1 fc0 sc0 ls2 ws0">这是因为传统的编译<span class="_ _2"></span>器是在发布软件之前编译为<span class="_ _2"></span>内部机器可执行的代码<span class="_ _2"></span>。即编译器不知道</div><div class="t m0 x6 h5 y4c ff2 fs1 fc0 sc0 ls2 ws0">代码所运行的处理器<span class="_ _2"></span>类型,例如该处理器是<span class="_ _1"> </span><span class="ff1 lsd">x86<span class="_ _3"> </span></span>兼容处理器还是<span class="_ _3"> </span><span class="ff1 lsd">Alpha<span class="_"> </span></span>处理器,这超出了</div><div class="t m0 x6 h5 y4d ff2 fs1 fc0 sc0 ls2 ws0">基本操作的范围。例<span class="_ _2"></span>如<span class="_ _3"> </span><span class="ff1 ls32 wsc">V<span class="_ _a"></span>isual Studio 6<span class="_ _1"> </span><span class="ff2 ls2 ws0">为一般的奔腾机器进行了优化,所以它生<span class="_ _2"></span>成的代码</span></span></div><div class="t m0 x6 h5 y4e ff2 fs1 fc0 sc0 ls2 ws0">就不能利用奔腾<span class="ff1 lsc wsd"> III<span class="_ _1"> </span></span>处理器的硬件特性。相反,<span class="ff1 lsf">JIT<span class="_"> </span></span>编译<span class="_ _2"></span>器不仅可以进行<span class="_ _1"> </span><span class="ff1 ls33 wse">V<span class="_ _9"></span>isual Studio 6<span class="_"> </span><span class="ff2 ls0 ws0">所</span></span></div><div class="t m0 x6 h5 y4f ff2 fs1 fc0 sc0 ls2 ws0">能完成的优化工作,<span class="_ _2"></span>还可以优化代码所运行的特<span class="_ _2"></span>定处理器。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h6 y50 ff4 fs1 fc0 sc0 ls2b ws0">3. <span class="_ _1"> </span><span class="ff6 ls2">语言的互操作性</span><span class="ls0"> </span></div><div class="t m0 x4 h5 y51 ff2 fs1 fc0 sc0 ls0 ws0">使用<span class="_ _3"> </span><span class="ff1 lsc">IL<span class="_"> </span></span><span class="ls2">不仅支持平台无关<span class="_ _2"></span>性,<span class="_ _13"></span>还支持语言的互操作性。<span class="_ _b"></span>简而言之,<span class="_ _13"></span>就是能将任何一种</span></div><div class="t m0 x6 h5 y52 ff2 fs1 fc0 sc0 ls2 ws0">语言编译为中间代码<span class="_ _2"></span>,编译好的代码可以与从其<span class="_ _2"></span>他语言编译过来的代码<span class="_ _2"></span>进行交互操作。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y53 ff2 fs1 fc0 sc0 ls2 ws0">那么除了<span class="_ _5"> </span><span class="ff1 ls3">C#</span>之外,还有什么语言可以<span class="_ _2"></span>通过<span class="ff1 ls7">.NET<span class="_ _5"> </span></span>进行交互<span class="_ _2"></span>操作呢?下面就简要讨论其</div><div class="t m0 x6 h5 y54 ff2 fs1 fc0 sc0 ls2 ws0">他常见语言如何与<span class="ff1 ls7">.N<span class="_ _2"></span>ET<span class="_"> </span><span class="ff2 ls2">交<span class="_ _2"></span>互操作。<span class="ff1 ls0"> </span></span></span></div><div class="t m0 x4 h6 y55 ff4 fs1 fc0 sc0 ls3 wsf">(1) Visual Basic 2005 </div><div class="t m0 x4 h5 y56 ff1 fs1 fc0 sc0 ls3 ws10">V<span class="_ _9"></span>isual Basic 6<span class="_"> </span><span class="ff2 ls0 ws0">在升级到<span class="_ _3"> </span></span><span class="lsf ws11">V<span class="_ _9"></span>isual Basic .NET 2002<span class="_"> </span><span class="ff2 ls2 ws0">时,<span class="_ _8"></span>经历了一<span class="_ _2"></span>番脱胎换骨的变化,<span class="_ _8"></span>才集</span></span></div><div class="t m0 x6 h5 y57 ff2 fs1 fc0 sc0 ls0 ws0">成到<span class="ff1 ls17 ws9">.NET<span class="_ _2"></span> Fram<span class="_ _2"></span>ework<span class="_ _1"> </span><span class="ff2 ls2 ws0">的第一版中。</span><span class="lsa ws12">V<span class="_ _a"></span>isual Basic <span class="_"> </span><span class="ff2 ls2 ws0">语言对<span class="_ _3"> </span></span><span class="ls5 ws10">V<span class="_ _9"></span>isual Basic 6<span class="_"> </span><span class="ff2 ls2 ws0">进行了很大的演化,</span></span></span></span></div><div class="t m0 x6 h5 y58 ff2 fs1 fc0 sc0 ls2 ws0">也就是说,<span class="_ _9"></span><span class="ff1 ls5 ws10">V<span class="_ _9"></span>isual Basic 6<span class="_"> </span><span class="ff2 ls2 ws0">并不适合运行</span><span class="ws0">.NET<span class="_"> </span><span class="ff2 ls2">程序。<span class="_ _a"></span>例如,<span class="_ _9"></span>它与<span class="_ _1"> </span><span class="ff1 ls34">COM<span class="_ _3"> </span></span>的高度集成,<span class="_ _9"></span>且只把</span></span></span></div><div class="t m0 x6 h5 y59 ff2 fs1 fc0 sc0 ls2 ws0">事件处理程序作为源<span class="_ _2"></span>代码显示给开发人员,大多<span class="_ _2"></span>数后台代码不能用作源<span class="_ _2"></span>代码。另外,它不</div><div class="t m0 x6 h5 y5a ff2 fs1 fc0 sc0 ls2 ws0">支持继承,<span class="ff1 ls35">V<span class="_ _9"></span>isual Basic<span class="_"> </span><span class="ff2 ls2">使用的标准数据类型也<span class="_ _2"></span>与<span class="ff1 ls7">.NE<span class="_ _2"></span>T<span class="_"> </span><span class="ff2 ls2">不兼容。</span><span class="ls0"> </span></span></span></span></div><div class="t m0 x4 h5 y5b ff1 fs1 fc0 sc0 ls5 ws10">V<span class="_ _9"></span>isual Basic 6<span class="_"> </span><span class="ff2 ls0 ws0">在<span class="_ _3"> </span><span class="ff1 lsd">2002<span class="_"> </span></span>年升级为<span class="_ _1"> </span></span><span class="ls9 ws13">V<span class="_ _9"></span>isual Basic .NE<span class="_ _7"></span>T<span class="ff2 ls0 ws0">,<span class="_ _15"></span>对<span class="_ _1"> </span><span class="ff1 ls36 ws14">Vi<span class="_ _d"></span>s<span class="_ _d"></span>u<span class="_ _17"></span>a<span class="_ _d"></span>l<span class="_ _d"></span> B<span class="_ _17"></span>a<span class="_ _d"></span>s<span class="_ _d"></span>i<span class="_ _17"></span>c<span class="_ _5"> </span></span><span class="ls2">进行的改变非常大,</span></span></span></div><div class="t m0 x6 h5 y5c ff2 fs1 fc0 sc0 ls2 ws0">完全可以把<span class="_ _1"> </span><span class="ff1 ls35 ws15">V<span class="_ _9"></span>isual Basic<span class="_ _3"> </span><span class="ff2 ls2 ws0">当作是一种新语言。现有<span class="_ _2"></span>的<span class="_ _1"> </span><span class="ff1 ls5 ws16">V<span class="_ _9"></span>isual Basic 6<span class="_ _3"> </span><span class="ff2 ls2 ws0">代码不能编译为<span class="_ _1"> </span><span class="ff1 ls36">Vi<span class="_ _17"></span>s<span class="_ _d"></span>u<span class="_ _d"></span>a<span class="_ _17"></span>l<span class="_ _d"></span> </span></span></span></span></span></div><div class="t m0 x6 h5 y5d ff1 fs1 fc0 sc0 ls37 ws17">Basic 2005<span class="_ _f"> </span><span class="ff2 ls2 ws0">代码<span class="ff1 ls0">(<span class="ff2">或<span class="_ _f"> </span></span><span class="ls38 ws18">V<span class="_ _9"></span>isual Basic .NET 2002<span class="_ _f"> </span><span class="ff2 ls0 ws0">和</span></span></span></span></div><div class="t m0 xf h5 y5e ff1 fs1 fc0 sc0 lsd ws0">2003<span class="_ _f"> </span><span class="ff2 ls0">代码<span class="ff1">)</span>,<span class="_ _e"></span>把<span class="_ _f"> </span><span class="ff1 lsa ws12">V<span class="_ _9"></span>isual Basic 6<span class="_ _f"> </span><span class="ff2 ls2 ws0">程序转换为<span class="_ _f"> </span><span class="ff1 ls36">Vi<span class="_ _d"></span>s<span class="_ _17"></span>u<span class="_ _d"></span>a<span class="_ _d"></span>l<span class="_ _17"></span> </span></span></span></span></div><div class="t m0 x6 h5 y5f ff1 fs1 fc0 sc0 ls37 ws19">Basic 2005<span class="_"> </span><span class="ff2 ls39 ws0">时,需要对代码进行大<span class="_ _7"></span>量的改动,但大多数修改工作都<span class="_ _7"></span>可以由<span class="_"> </span></span><span class="ls32 ws1a">V<span class="_ _a"></span>isual Studio </span></div><div class="t m0 x6 h5 y60 ff1 fs1 fc0 sc0 lsa ws12">2005(V<span class="_ _9"></span>isual Studio<span class="_"> </span><span class="ff2 ls0 ws0">的升级版本,用于与<span class="ff1 ls5">.NET<span class="_"> </span></span>一起使用<span class="ff1">)</span><span class="ls2">自动完成。如果把<span class="_ _1"> </span></span></span><span class="ls5 ws10">V<span class="_ _9"></span>isual Basic 6<span class="_"> </span><span class="ff2 ls0 ws0">项</span></span></div><div class="t m0 x6 h5 y61 ff2 fs1 fc0 sc0 ls0 ws0">目读到<span class="_ _3"> </span><span class="ff1 ls3a ws1b">V<span class="_ _a"></span>i<span class="_ _7"></span>sual S<span class="_ _2"></span>tudio 2005<span class="_"> </span><span class="ff2 ls0 ws0">中,<span class="_ _13"></span><span class="ff1 ls3a ws1b">V<span class="_ _9"></span>isual Studio 2005<span class="_"> </span><span class="ff2 ls2 ws0">就<span class="_ _2"></span>会升级该项目,<span class="_ _b"></span>也就是说把<span class="_ _1"> </span><span class="ff1 ls3b ws1c">V<span class="_ _9"></span>isual B<span class="_ _7"></span>asic </span></span></span></span></span></div><div class="t m0 x6 h5 y62 ff1 fs1 fc0 sc0 ls0 ws0">6<span class="_"> </span><span class="ff2">源代码重写为<span class="_ _3"> </span></span><span class="ls2e ws1d">V<span class="_ _9"></span>isual Basic 2005<span class="_ _3"> </span><span class="ff2 ls2 ws0">源代<span class="_ _2"></span>码。虽然这意味着其<span class="_ _2"></span>中的工作已大大减轻,<span class="_ _2"></span>但用户</span></span></div><div class="t m0 x6 h5 y63 ff2 fs1 fc0 sc0 ls2 ws0">仍需要检查新的<span class="_ _1"> </span><span class="ff1 ls3c ws1e">V<span class="_ _9"></span>isual Basic 2005<span class="_ _1"> </span><span class="ff2 ls2 ws0">代码,以确保项目仍可正确工作,因为这种<span class="_ _2"></span>转换并不十</span></span></div><div class="t m0 x6 h5 y64 ff2 fs1 fc0 sc0 ls2 ws0">分完美。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y65 ff2 fs1 fc0 sc0 ls2 ws0">这种语言升级的一个<span class="_ _2"></span>副作用是不能再把<span class="_ _1"> </span><span class="ff1 ls3c ws1e">V<span class="_ _9"></span>isual Basic 2005<span class="_ _3"> </span><span class="ff2 ls2 ws0">编译为内<span class="_ _2"></span>部可执行代码了。</span></span></div><div class="t m0 x6 h5 y66 ff1 fs1 fc0 sc0 lsf ws11">V<span class="_ _9"></span>isual Basic 2005<span class="_"> </span><span class="ff2 ls2 ws0">只编译为中间语言,<span class="_ _8"></span>就像<span class="_ _1"> </span><span class="ff1 ls3">C#</span>一样。<span class="_ _8"></span>如果需要继续使用<span class="_ _3"> </span><span class="ff1 lsa ws12">V<span class="_ _a"></span>isual Basic 6<span class="_"> </span><span class="ff2 ls2 ws0">编写</span></span></span></div><div class="t m0 x6 h5 y67 ff2 fs1 fc0 sc0 ls0 ws0">程序,<span class="_ _18"></span><span class="ls2">就可以这么做,<span class="_ _19"></span>但生成的可执行代码会完<span class="_ _2"></span>全忽略<span class="ff1 ls4 ws1f">.NET<span class="_ _9"></span> Framewor<span class="_ _2"></span>k<span class="ff2 ls0 ws0">,<span class="_ _19"></span><span class="ls2">如果继续把<span class="_ _3"> </span><span class="ff1 ls36">Vi<span class="_ _d"></span>s<span class="_ _d"></span>u<span class="_ _d"></span>a<span class="_ _17"></span>l<span class="_ _d"></span> </span></span></span></span></span></div><div class="t m0 x6 h5 y68 ff1 fs1 fc0 sc0 ls33 ws0">Studio<span class="_ _1"> </span><span class="ff2 ls2">作为开发环境,就<span class="_ _2"></span>需要安装<span class="_ _1"> </span><span class="ff1 ls32 ws20">V<span class="_ _9"></span>isual Studio 6<span class="ff2 ls0 ws0">。<span class="ff1"> </span></span></span></span></div><div class="t m0 x4 h6 y69 ff4 fs1 fc0 sc0 ls0 ws0"> </div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>
<div id="pf4" class="pf w0 h0" data-page-no="4"><div class="pc pc4 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://csdnimg.cn/release/download_crawler_static/2366853/bg4.jpg"><div class="t m0 x6 h6 y26 ff6 fs0 fc0 sc0 ls0 ws0">第Ⅰ部分<span class="ff4 ls1a"> C<span class="_ _b"></span>#<span class="_ _b"></span> <span class="ff6 ls0">语<span class="ff4"> <span class="_ _c"> </span></span>言<span class="ff4 fs1"> </span></span></span></div><div class="t m0 x2 h2 y2 ff1 fs0 fc0 sc0 ls0 ws0"> </div><div class="t m0 xb hb y27 ff5 fs1 fc0 sc0 ls0 ws0">6</div><div class="t m0 x4 h6 y6a ff4 fs1 fc0 sc0 lsc ws0">(2)<span class="ff1 ls0"> </span><span class="ls3d ws21">Visua<span class="_ _2"></span>l C++ 2005<span class="ff1 ls0 ws0"> </span></span></div><div class="t m0 x4 h5 y6b ff1 fs1 fc0 sc0 ls3 ws22">V<span class="_ _9"></span>isual C++ 6<span class="_ _3"> </span><span class="ff2 ls0 ws0">有许多<span class="_ _1"> </span><span class="ff1 ls3e">Micro<span class="_ _7"></span>soft<span class="_"> </span></span>对<span class="_ _1"> </span><span class="ff1 lsd">Window<span class="_ _2"></span>s<span class="_"> </span><span class="ff2 ls2">的特定扩展。通过<span class="_ _1"> </span></span><span class="ls36 ws23">Vi<span class="_ _d"></span>s<span class="_ _17"></span>u<span class="_ _d"></span>a<span class="_ _d"></span>l<span class="_ _17"></span> C<span class="_ _d"></span>+<span class="_ _d"></span>+<span class="_ _17"></span> .<span class="_ _d"></span>N<span class="_ _d"></span>E<span class="_ _17"></span>T<span class="_ _d"></span></span><span class="ff2 ls2">,又加</span></span></span></div><div class="t m0 x6 h5 y6c ff2 fs1 fc0 sc0 ls2 ws0">入了更多的扩展内容,<span class="_ _9"></span>来支持<span class="ff1 ls3f ws12">.NE<span class="_ _2"></span>T F<span class="_ _2"></span>ram<span class="_ _2"></span>ewor<span class="_ _2"></span>k<span class="ff2 ls40 ws0">。现<span class="_ _7"></span>有<span class="_ _7"></span>的<span class="_ _5"> </span><span class="ff1 ls12">C++</span><span class="ls2">源代码会继续编译为<span class="_ _2"></span>内部可执</span></span></span></div><div class="t m0 x6 h5 y6d ff2 fs1 fc0 sc0 ls2 ws0">行代码,<span class="_ _b"></span>不会有修改,<span class="_ _b"></span>但它会独立于<span class="ff1 ls5">.NET<span class="_"> </span></span>运行库运行。<span class="_ _b"></span>如果让<span class="_ _1"> </span><span class="ff1 ls12">C++<span class="_ _7"></span></span>代码在<span class="ff1 ls4 ws1f">.NE<span class="_ _2"></span>T<span class="_ _2"></span> Framew<span class="_ _2"></span>ork</span></div><div class="t m0 x6 h5 y6e ff2 fs1 fc0 sc0 ls2 ws0">中运行,就可以在代<span class="_ _2"></span>码的开头添加下述命令:<span class="ff1 ls0"> </span></div><div class="t m0 x4 he y6f ff8 fs0 fc0 sc0 ls41 ws24">#using <mscorli<span class="_ _7"></span>b.dll> </div><div class="t m0 x4 h5 y70 ff2 fs1 fc0 sc0 ls2 ws0">还可以把标记<span class="ff1 ls37">/clr<span class="_ _12"> </span></span>传递给编译器,这样编译器假定要<span class="_ _7"></span>编译托管代码,因此会生成<span class="_ _7"></span>中间</div><div class="t m0 x6 h5 y71 ff2 fs1 fc0 sc0 ls1e ws0">语言,而不是内部机<span class="_ _2"></span>器码。<span class="ff1 ls12">C++</span>的一个有趣的问题是在编译托<span class="_ _2"></span>管代码时,编译器可以<span class="_ _2"></span>生成</div><div class="t m0 x6 h5 y72 ff2 fs1 fc0 sc0 ls2 ws0">包含内嵌本机可执行<span class="_ _2"></span>代码的<span class="_ _1"> </span><span class="ff1 lsc">IL<span class="_ _7"></span></span><span class="ls0">。<span class="_ _15"></span>这表示在<span class="_ _3"> </span><span class="ff1 ls12">C++</span><span class="ls2">代码中可以把托管类型和非托管<span class="_ _2"></span>类型合并起</span></span></div><div class="t m0 x6 h5 y73 ff2 fs1 fc0 sc0 ls2 ws0">来,因此托管<span class="_ _1"> </span><span class="ff1 ls12">C++</span>代码:<span class="ff1 ls0"> </span></div><div class="t m0 x4 he y74 ff8 fs0 fc0 sc0 ls41 ws0">class MyCla<span class="_ _7"></span>ss </div><div class="t m0 x4 he y75 ff8 fs0 fc0 sc0 ls41 ws0">{ </div><div class="t m0 x4 h5 y76 ff2 fs1 fc0 sc0 ls2 ws0">定义了一个普通的<span class="_ _1"> </span><span class="ff1 ls12">C++</span>类,而代码:<span class="ff1 ls0"> </span></div><div class="t m0 x4 he y77 ff8 fs0 fc0 sc0 ls41 ws0">__gc class <span class="_ _7"></span>MyClass </div><div class="t m0 x4 he y78 ff8 fs0 fc0 sc0 ls41 ws0">{ </div><div class="t m0 x4 h5 y79 ff2 fs1 fc0 sc0 ls2 ws0">生成了一个托管类,<span class="_ _2"></span>就好像使用<span class="_ _1a"> </span><span class="ff1 ls3">C#</span><span class="ls0">或<span class="_ _1a"> </span><span class="ff1 ls2e ws25">V<span class="_ _9"></span>isual Basic 2005<span class="_ _1a"> </span><span class="ff2 ls2 ws0">编写类一样。实际上,托管</span></span></span></div><div class="t m0 x6 h5 y7a ff1 fs1 fc0 sc0 ls12 ws0">C++<span class="ff2 ls0">比<span class="_ _1"> </span></span><span class="ls3">C#<span class="ff2 ls2">更优越的一点是可以在托管<span class="_ _1"> </span></span></span>C++<span class="ff2 ls2">代码中调用非托管<span class="_ _1"> </span></span>C++<span class="ff2 ls2">类,<span class="_ _9"></span>而不必采用<span class="_ _1"> </span><span class="ff1 ls42">COM<span class="_ _3"> </span></span><span class="ls0">交</span></span></div><div class="t m0 x6 h5 y7b ff2 fs1 fc0 sc0 ls2 ws0">互功能。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y7c ff2 fs1 fc0 sc0 ls2 ws0">如果在托管类型上试<span class="_ _2"></span>图使用<span class="ff1 ls8">.NET<span class="_ _1"> </span></span>不支持的特性<span class="ff1 ls0">(</span>例如,<span class="_ _a"></span>模板或类的多继承<span class="ff1 ls0">)</span>,<span class="_ _9"></span>编译器就</div><div class="t m0 x6 h5 y7d ff2 fs1 fc0 sc0 ls2 ws0">会出现一个错误。<span class="_ _13"></span>另外,<span class="_ _8"></span>在使用托管类时,<span class="_ _13"></span>还需要使用非标准的<span class="_ _1"> </span><span class="ff1 ls12">C++</span>特性<span class="ff1 ls0">(</span>例如上述代码中</div><div class="t m0 x6 h5 y7e ff2 fs1 fc0 sc0 ls0 ws0">的<span class="ff1 lsd">__gc<span class="_"> </span></span>关键字<span class="ff9">)</span>。<span class="ff1"> </span></div><div class="t m0 x4 h5 y7f ff2 fs1 fc0 sc0 ls0 ws0">因为<span class="_ _1"> </span><span class="ff1 ls12">C++<span class="_ _7"></span></span><span class="ls2">允许低级指针操作,<span class="_ _10"></span><span class="ff1 ls43">C++<span class="ff2 ls2">编译器不能生成可以通过<span class="_ _1"> </span></span><span class="ls11">CLR<span class="_"> </span><span class="ff2 ls2">内存类型安全测试的</span></span></span></span></div><div class="t m0 x6 h5 y80 ff2 fs1 fc0 sc0 ls0 ws0">代码。<span class="_ _b"></span>如果<span class="_ _1"> </span><span class="ff1 ls43">CLR<span class="_"> </span></span><span class="ls2">把代码标识<span class="_ _2"></span>为内存类型安全是非常<span class="_ _2"></span>重要的,<span class="_ _15"></span>就需要用其他一些语言编写源</span></div><div class="t m0 x6 h5 y81 ff2 fs1 fc0 sc0 ls2 ws0">代码,例如<span class="_ _1"> </span><span class="ff1 ls2e">C# <span class="_"> </span></span><span class="ls0">或<span class="_ _3"> </span><span class="ff1 ls2e ws26">V<span class="_ _9"></span>isual Basic 2005<span class="ff2 ls0 ws0">。<span class="ff1"> </span></span></span></span></div><div class="t m0 x4 h6 y82 ff4 fs1 fc0 sc0 lsc ws0">(3)<span class="ff1 ls0"> </span><span class="ls44 ws27">Visual J# 2005</span><span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y83 ff2 fs1 fc0 sc0 ls2 ws0">最新添加的语言是<span class="_ _1"> </span><span class="ff1 ls2e ws28">V<span class="_ _9"></span>is<span class="_ _2"></span>ua<span class="_ _2"></span>l J# 2005<span class="ff2 ls0 ws0">。在</span><span class="ls38 ws29">.NET Framework 1.1<span class="_ _1"> </span><span class="ff2 ls2 ws0">版本推出之前,用户必须下</span></span></span></div><div class="t m0 x6 h5 y84 ff2 fs1 fc0 sc0 ls2 ws0">载相应的软件,<span class="_ _8"></span>才能使用<span class="_ _1"> </span><span class="ff1 ls44">J#</span><span class="ls45">。现<span class="_ _1b"> </span>在<span class="_"> </span><span class="ff1 ls30">J#</span></span>语<span class="_ _2"></span>言内置于<span class="ff1 ls46 ws2a">.NE<span class="_ _2"></span>T<span class="_ _2"></span> Framewor<span class="_ _2"></span>k<span class="_"> </span><span class="ff2 ls2 ws0">中。<span class="_ _8"></span>因此,<span class="_ _8"></span><span class="ff1 ls44">J#<span class="ff2 ls2">用户可以利</span></span></span></span></div><div class="t m0 x6 h5 y85 ff2 fs1 fc0 sc0 ls0 ws0">用<span class="_ _3"> </span><span class="ff1 ls47 ws2b">V<span class="_ _a"></span>isu<span class="_ _7"></span>al Studio 2005<span class="_"> </span><span class="ff2 ls48 ws0">的所有常见特性。<span class="ff1 ls12">Microsoft<span class="_"> </span></span><span class="ls2">希望大多数<span class="_ _1"> </span><span class="ff1 ls49">J++</span>用户认为他们在使用<span class="ff1 ls7">.NE<span class="_ _2"></span>T</span></span></span></span></div><div class="t m0 x6 h5 y86 ff2 fs1 fc0 sc0 ls2 ws0">时,将很容易使用<span class="_ _3"> </span><span class="ff1 ls44">J#<span class="_ _7"></span></span><span class="ls0">。<span class="ff1 ls30">J#</span>不使用<span class="_ _5"> </span><span class="ff1 ls26">Java<span class="_ _5"> </span></span></span>运行库,而是使用与其他<span class="ff1 ls5">.NET<span class="_ _5"> </span></span><span class="ls0">兼容语言一样的<span class="_ _7"></span>基类</span></div><div class="t m0 x6 h5 y87 ff2 fs1 fc0 sc0 ls2 ws0">库。这说明,与<span class="_ _1"> </span><span class="ff1 ls3">C#</span><span class="ls0">和<span class="_ _3"> </span><span class="ff1 ls33 ws2c">V<span class="_ _a"></span>i<span class="_ _7"></span>sual Basic 2005<span class="_ _1"> </span><span class="ff2 ls0 ws0">一样,可<span class="_ _7"></span>以使用<span class="_ _3"> </span><span class="ff1 ls44">J#</span><span class="ls2">创建<span class="_ _1"> </span></span></span><span class="ls49 ws2d">ASP<span class="_ _8"></span>.NET W<span class="_ _8"></span>eb<span class="_ _3"> </span><span class="ff2 ls2 ws0">应用程序、</span></span></span></span></div><div class="t m0 x6 h5 y88 ff1 fs1 fc0 sc0 lsd ws0">W<span class="_ _9"></span>indows<span class="_"> </span><span class="ff2 ls2">窗体、</span><span class="ls4a ws2e">XML<span class="_ _2"></span> W<span class="_ _a"></span>eb<span class="_ _3"> </span><span class="ff2 ls2 ws0">服务和其他应用程序。<span class="ff1 ls0"> </span></span></span></div><div class="t m0 x4 h6 y89 ff4 fs1 fc0 sc0 lsc ws0">(4)</div><div class="t m0 x10 hf y8a ff1 fs1 fc0 sc0 ls0 ws0"> <span class="_"> </span><span class="ff6 ls2">脚本语言</span> </div><div class="t m0 x4 h5 y8b ff2 fs1 fc0 sc0 ls2 ws0">脚本语言仍在使用之<span class="_ _2"></span>中,<span class="_ _10"></span><span class="ls0">但由<span class="_ _7"></span>于<span class="ff1 ls7">.NET<span class="_"> </span></span><span class="ls2">的<span class="_ _2"></span>推出,<span class="_ _10"></span>它们的重要性在降低。<span class="_ _10"></span>与此同时,<span class="_ _19"></span><span class="ff1 ls1f">JScript</span></span></span></div><div class="t m0 x6 h5 y8c ff2 fs1 fc0 sc0 ls2 ws0">升级到了<span class="_ _1a"> </span><span class="ff1 lsa">JScript.NET</span>。现在<span class="_ _1a"> </span><span class="ff1 ls4b">ASP<span class="_ _a"></span>.NET<span class="_ _1c"> </span><span class="ff2 ls2">页面可以用<span class="_ _1a"> </span></span><span class="ls32">JScript.NET<span class="_ _1a"> </span><span class="ff2 ls2">编写,可以把<span class="_ _1a"> </span></span><span class="ls33">JSc<span class="_ _7"></span>ript.NET</span></span></span></div><div class="t m0 x6 h5 y8d ff2 fs1 fc0 sc0 ls2 ws0">当作一种编译语言来<span class="_ _2"></span>运行,<span class="_ _e"></span>而不是解释性的语言,<span class="_ _e"></span>也可以编写强<span class="_ _2"></span>类型化的<span class="_ _1"> </span><span class="ff1 ls3">JScript.NET<span class="_"> </span></span><span class="ls0">代码<span class="_ _7"></span>。</span></div><div class="t m0 x6 h5 y8e ff2 fs1 fc0 sc0 ls0 ws0">有了<span class="_ _3"> </span><span class="ff1 ls49">ASP<span class="_ _8"></span>.NET<span class="_"> </span><span class="ff2 ls2">后,<span class="_ _b"></span>就没有必要在服务器端的<span class="_ _1"> </span><span class="ff1 ls4c">We<span class="_ _17"></span>b<span class="_ _1a"> </span></span>页面上使用脚<span class="_ _2"></span>本语言了,<span class="_ _b"></span>但<span class="_ _3"> </span><span class="ff1 ls4b">VBA<span class="_"> </span></span><span class="ls1e">仍用作</span></span></span></div><div class="t m0 x6 h5 y8f ff1 fs1 fc0 sc0 ls0 ws0">Office<span class="_"> </span><span class="ff2 ls2">文档和<span class="_ _1"> </span></span><span class="ls33 wse">V<span class="_ _9"></span>isual Studio<span class="_ _1"> </span><span class="ff2 ls0 ws0">宏语言。<span class="ff1"> </span></span></span></div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>
<div id="pf5" class="pf w0 h0" data-page-no="5"><div class="pc pc5 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://csdnimg.cn/release/download_crawler_static/2366853/bg5.jpg"><div class="t m0 xd hd y26 ff6 fs0 fc0 sc0 ls0 ws0">第<span class="_ _c"> </span><span class="ff4">1<span class="_"> </span></span>章<span class="ff4 ls1a"> .<span class="_ _b"></span>N<span class="_ _b"></span>E<span class="_ _b"></span>T<span class="_ _7"></span><span class="ff6 ls0">体系结构<span class="ff4"> </span></span></span></div><div class="t m0 x2 h2 y45 ff1 fs0 fc0 sc0 ls0 ws0"> </div><div class="t m0 xe hb y46 ff5 fs1 fc0 sc0 ls31 ws0">7 </div><div class="t m0 x4 h6 y3 ff4 fs1 fc0 sc0 lsc ws0">(5)<span class="ff1 ls0"> </span><span class="ls4d">COM<span class="_"> </span><span class="ff6 ls0">和<span class="_ _3"> </span></span>COM+<span class="ff1 ls0"> </span></span></div><div class="t m0 x4 h5 y4 ff2 fs1 fc0 sc0 ls1e ws0">从技术上讲,<span class="ff1 ls4e">COM <span class="_"> </span></span><span class="ls0">和<span class="ff1 ls3e ws2f"> COM+</span></span>并不是面向<span class="ff1 ls7">.N<span class="_ _2"></span>ET<span class="_ _6"> </span><span class="ff2 ls1e">的技术,因为基于它们的组件不能编</span></span></div><div class="t m0 x6 h5 y5 ff2 fs1 fc0 sc0 ls0 ws0">译为<span class="_ _3"> </span><span class="ff1 lsc">IL(</span><span class="ls2">但如果原来的<span class="_ _1"> </span><span class="ff1 ls42">COM<span class="_"> </span></span></span>组件是用<span class="_ _3"> </span><span class="ff1 ls12">C++</span><span class="ls2">编写的,<span class="_ _b"></span>使用托管<span class="_ _1"> </span><span class="ff1 ls3">C++</span>,<span class="_ _b"></span>在某种程度上可以这么</span></div><div class="t m0 x6 h5 y6 ff2 fs1 fc0 sc0 ls0 ws0">做<span class="ff1">)</span><span class="ls2">。但是,<span class="ff1 ls3e">COM+<span class="_ _7"></span></span>仍然是一个重要的工具,因<span class="_ _7"></span>为其特性没有在<span class="ff1 ls7">.NET<span class="_ _6"> </span></span>中完全实现<span class="_ _7"></span>。另外,</span></div><div class="t m0 x6 h5 y47 ff1 fs1 fc0 sc0 ls34 ws0">COM<span class="_"> </span><span class="ff2 ls2">组件仍可以使用—<span class="_ _8"></span>—<span class="_ _a"></span><span class="ff1 ls4a">.NET<span class="_ _3"> </span><span class="ff2 ls2">组合了<span class="_ _1"> </span></span><span class="ls34">COM<span class="_ _3"> </span><span class="ff2 ls2">的互操作性,<span class="_ _a"></span>从而使托管代码可以调用<span class="_ _1"> </span><span class="ff1 ls42">COM</span></span></span></span></span></div><div class="t m0 x6 h5 y48 ff2 fs1 fc0 sc0 ls0 ws0">组件,<span class="ff1 ls43">COM<span class="_ _3"> </span></span><span class="ls2">组件也可以调用托管代码</span><span class="ff1">(</span>见第<span class="_ _3"> </span><span class="ff1 lsd">33<span class="_ _5"> </span></span>章<span class="ff1">)</span><span class="ls2">。在一般情况下,把新组件编<span class="_ _2"></span>写为<span class="ff1 ls4f">.NET</span></span></div><div class="t m0 x6 h5 y49 ff2 fs1 fc0 sc0 ls2 ws0">组件,大多是为了方<span class="_ _2"></span>便,因为这样可以利用<span class="ff1 ls8">.N<span class="_ _2"></span>ET<span class="_"> </span><span class="ff2 ls2">基类和托管<span class="_ _2"></span>代码的其他优点。<span class="ff1 ls0"> </span></span></span></div><div class="t m0 x6 h8 y90 ff5 fs4 fc0 sc0 ls13 ws7">1.3 <span class="ff6 sc1 ls50 ws0">中间语言</span><span class="ls0 ws0"> </span></div><div class="t m0 x4 h5 y91 ff2 fs1 fc0 sc0 ls2 ws0">通过前面的学习,我<span class="_ _2"></span>们理解了<span class="_ _1"> </span><span class="ff1 lsf">Microsoft<span class="_ _3"> </span></span>中间语言显然在<span class="ff1 ls51 ws30">.NET<span class="_ _9"></span> Framew<span class="_ _2"></span>ork<span class="_ _1"> </span><span class="ff2 ls2 ws0">中有非常重</span></span></div><div class="t m0 x6 h5 y92 ff2 fs1 fc0 sc0 ls2 ws0">要的作用。<span class="ff1 ls43">C#</span>开发人员应明白,<span class="ff1 ls3">C#<span class="_ _7"></span></span>代码在执行前要编译为中<span class="_ _7"></span>间语言<span class="ff1 ls0">(</span><span class="ls1e">实际上,<span class="ff1 ls3">C#</span>编译器仅</span></div><div class="t m0 x6 h5 y93 ff2 fs1 fc0 sc0 ls2 ws0">编译为托管代码<span class="ff1 ls0">)</span>,<span class="_ _a"></span>这是有意义的,<span class="_ _a"></span>现在应详细讨论一下<span class="_ _1"> </span><span class="ff1 lsc">IL<span class="_"> </span></span>的主要特征,<span class="_ _9"></span>因为面向<span class="ff1 ls7">.NE<span class="_ _2"></span>T<span class="_"> </span><span class="ff2 ls0">的</span></span></div><div class="t m0 x6 h5 y94 ff2 fs1 fc0 sc0 ls2 ws0">所有语言在逻辑上都<span class="_ _2"></span>需要支持<span class="_ _1"> </span><span class="ff1 lsc">IL<span class="_ _3"> </span></span>的主要特征。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 y95 ff2 fs1 fc0 sc0 ls2 ws0">下面就是中间语言的<span class="_ _2"></span>主要特征:<span class="ff1 ls0"> </span></div><div class="t m0 x4 h6 y96 ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">面向对象和使用接口</span><span class="ff1"> </span></span></div><div class="t m0 x4 h6 y97 ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">值类型和引用类型之<span class="_ _2"></span>间的巨大差别<span class="ff1 ls0"> </span></span></span></div><div class="t m0 x4 h6 y98 ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">强数据类型</span><span class="ff1"> </span></span></div><div class="t m0 x4 h6 y99 ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">使用异常来处理错误</span><span class="ff1"> </span></span></div><div class="t m0 x4 h6 y9a ff3 fs1 fc0 sc0 ls0 ws0">●<span class="ff4"> <span class="_ _4"> </span><span class="ff2 ls2">使用特性<span class="ff1 ls2e">(attribute) </span></span></span></div><div class="t m0 x4 h5 y9b ff2 fs1 fc0 sc0 ls2 ws0">下面详细讨论这些特<span class="_ _2"></span>征。<span class="ff1 ls0"> </span></div><div class="t m0 x6 hc y9c ff4 fs7 fc0 sc0 ls52 ws31">1.3.1 <span class="ff6 ls53 ws0">面向对象和接口的支持<span class="ff4 ls0"> </span></span></div><div class="t m0 x4 h5 y9d ff1 fs1 fc0 sc0 ls4a ws0">.NET<span class="_"> </span><span class="ff2 ls2">的语言无关性还有一些实际的限<span class="_ _2"></span>制。<span class="_ _16"></span>中间语言在设计时就打算实现某些特殊<span class="_ _2"></span>的编</span></div><div class="t m0 x6 h5 y9e ff2 fs1 fc0 sc0 ls2 ws0">程方法,这表示面向<span class="_ _2"></span>它的语言必须与编程方法兼<span class="_ _2"></span>容,<span class="ff1 lsf">Microsoft<span class="_ _1c"> </span></span><span class="ls0">为<span class="_ _1a"> </span><span class="ff1 lsc">IL<span class="_ _1c"> </span></span></span>选择的特定道路是传</div><div class="t m0 x6 h5 y9f ff2 fs1 fc0 sc0 ls2 ws0">统的面向对象的编程<span class="_ _2"></span>,带有类的单一继承性。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h6 ya0 ff6 fs1 fc0 sc0 ls0 ws0">注意:<span class="ff4"> </span></div><div class="t m0 x4 h10 ya1 ffa fs1 fc0 sc0 ls54 ws0">不熟悉面向对象概<span class="_ _7"></span>念的读者应参考附录<span class="_ _12"> </span><span class="ff1 ls0">A<span class="_ _17"></span></span>,获得更多的信息。附录<span class="_ _12"> </span><span class="ff1 ls0">A<span class="_ _1d"> </span></span><span class="ls55">可以从</span></div><div class="t m0 x6 h10 ya2 ff1 fs1 fc0 sc0 lsb ws0">www<span class="_ _9"></span>.wrox.co<span class="_ _7"></span>m<span class="_"> </span><span class="ffa ls2">上下载。</span><span class="ls0"> </span></div><div class="t m0 x4 h5 ya3 ff2 fs1 fc0 sc0 ls2 ws0">除了传统的面向对象<span class="_ _2"></span>编程外,<span class="_ _18"></span>中间语言还引入了接口的概<span class="_ _2"></span>念,<span class="_ _18"></span>它们显示了在带有<span class="_ _1"> </span><span class="ff1 ls43">COM</span></div><div class="t m0 x6 h5 ya4 ff2 fs1 fc0 sc0 ls0 ws0">的<span class="_ _1"> </span><span class="ff1 ls56">W<span class="_ _2"></span>indows<span class="_"> </span><span class="ff2 ls2">下的第一个实<span class="_ _2"></span>现方式。<span class="_ _e"></span><span class="ff1 ls5">.NET<span class="_"> </span><span class="ff2 ls2">接口<span class="_ _2"></span>与<span class="_ _1"> </span><span class="ff1 ls43">COM<span class="_"> </span></span>接口不同,<span class="_ _1e"></span>它们不需要支持任何<span class="_ _1"> </span><span class="ff1 ls34">COM</span></span></span></span></span></div><div class="t m0 x6 h5 ya5 ff2 fs1 fc0 sc0 ls2 ws0">基础结构,例<span class="_ _2"></span>如,它们不<span class="_ _2"></span>是派生自<span class="_ _1"> </span><span class="ff1 ls2c">IUnknown</span>,也没有对应的<span class="_ _1"> </span><span class="ff1 ls49">GUID</span><span class="ls0">。但它们与<span class="_ _1"> </span><span class="ff1 ls43">COM<span class="_"> </span></span>接口</span></div><div class="t m0 x6 h5 ya6 ff2 fs1 fc0 sc0 ls2 ws0">共享下述理念:提供<span class="_ _2"></span>一个契约,实现给定接口的<span class="_ _2"></span>类必须提供该接口指定<span class="_ _2"></span>的方法和属性的实</div><div class="t m0 x6 h5 ya7 ff2 fs1 fc0 sc0 ls2 ws0">现方式。<span class="ff1 ls0"> </span></div><div class="t m0 x4 h5 ya8 ff2 fs1 fc0 sc0 ls2 ws0">前面介绍了使用<span class="ff1 ls8">.N<span class="_ _2"></span>ET<span class="_"> </span><span class="ff2 ls2">意味<span class="_ _2"></span>着要编译为中间语言,<span class="_ _16"></span>即需要使用传统的面向对<span class="_ _2"></span>象的方法来</span></span></div><div class="t m0 x6 h5 ya9 ff2 fs1 fc0 sc0 ls2 ws0">编程。<span class="_ _b"></span>但这并不能提供语言<span class="_ _2"></span>的互操作性。<span class="_ _b"></span>毕竟,<span class="_ _b"></span><span class="ff1 ls43">C++<span class="_ _2"></span><span class="ff2 ls0">和<span class="_ _1"> </span><span class="ff1 lsf">Java<span class="_ _3"> </span></span><span class="ls2">都使用相同的面向对象的范型,</span></span></span></div><div class="t m0 x6 h5 yaa ff2 fs1 fc0 sc0 ls2 ws0">但它们仍不是可交互<span class="_ _2"></span>操作的语言。下面需要详细<span class="_ _2"></span>探讨一下语言互操作性<span class="_ _2"></span>的概念。<span class="ff1 ls0"> </span></div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>