Wrox的C#高级编程第三版第一部分第一章(1~7页)

第一章        .NET架构

      阅读本书你会发现,本书通篇都强调,C#语言决不该被孤立的看待,它必须与.NET Framework一起考虑。C#编译器是以.NET为特定目标的,所以这就意味着用C#写出来的代码必须运行在.NET Framework.的支持上。这样,对C#就有两个重要的推论:

       C#的体系结构和方法论反映了.NET的根本方法论。

    在许多情况下,C#的许多专用语言特性依赖于.NET的特性或者.NET基础类。

    由于这种依赖关系,在开始C#编程之前,理解.NET的体系结构和方法论是重要的。这也正是本章的目的。

    我们首先会了解一下当所有以.NET为目标架构的语言(包括C#)被编译和运行时都发生了什么。一旦我们有了大致的了解,我们将更加详细地了解一下Microsoft Intermediate Language (MSIL or simply IL).NET上面所有的语言最终都会被编译为这种汇编语言。特别的,我们将了解一下ILCommon Type System (CTS)Common Language Specification (CLS)是怎样共同作用使得.NET下面的语言可以协同工作的。我们也要讨论各种语言(Visual Basic C++)怎样适合.NET的。

       了解完这些后,我们将要继续了解一下.NET的其他特性,包括程序集、命名空间和.NET基础类。最后结束这一章之前我们要像C#开发人员一样对可以创建的应用程序的种类做一个大致的了解。

1.1      C#.NET的关系

相比较其他语言来说,C#是一种新的编程语言,并且以下两个方面体现了他的重要性:

       它是专门为微软.NET框架(一个为了开发、部署和执行分布式应用软件而设计的功能丰富的平台)设计的。

    它是一种基于现代面向对象设计方法的语言,在他设计时,面向对象原则已经得到显著应用20年之久,而且微软吸收了所有这些面向对象语言的经验。

    一个重要的问题是要弄明白C#本身就是一种语言。尽管它是设计来产生.NET环境下的代码的,但是它不是.NET的一部分。还有一些特性.NET支持,但是C#并不支持,而且可能更令你惊奇的是,还有一些C#语言的特性.NET竟然不支持!(例如,一些运算符重载)

    但是,因为C#语言是用于.NET的,所以对我们来说如果我们想要用C#开发出高效的软件,了解.NET Framework就是重要的。因此,在这一章,我们将要花些时间迅速透过表层来观察一下.NET。好,我们开始吧!

1.2      公共语言运行时

    .NET Framework的核心是运行时执行环境,其被大家称为公共语言运行时(CLR)或者.NET运行时。在CLR的控制下运行的代码常常本称作托管代码。

    但是,在被CLR执行之前,所有我们开发的源代码(用C#或者其他的语言)都需要被编译。这样的编译需要两个步骤:

    1. 将源代码编译为中间语言(IL代码

    2. CLR将中间语言代码编译为特定平台上面的代码

    这两步编译过程是非常重要的,因为中间语言(IL的存在正是.NET众多优点的关键。好,让我们来看看为什么。

1.2.1        托管代码的优点

   Microsoft中间语言与Java字节码共享一种思路,他们都是一种语法简单的低级语言(建立在数字代码基础上,而不是文本代码),可以被快速的翻译为本地机器码。代码有这样设计良好并且通用的语法是意义重大的优点。

1.2.1.1              平台无关性

    首先,这就意味着包含字节代码指令的相同的文件可以被部署在任何的平台,在运行时编译过程的最后一个阶段可以很容易的完成,所以代码可以运行在特定的平台上。换句话说,源代码被编译成中间语言使得我们可以获得.NET的平台无关性,这和在Java平台上源代码被编译为Java字节码以获得平台无关性的道理是一样的。

    你应该注意到.NET这种平台无关性目前还是理论上的,因为在本书写作的时候,还只有在Windows平台上才完全实现了.NET。但是,已经有一个部分实现的.NET(参见Mono项目,一个正在致力于建立于开源平台之上的.NET,具体请访问www.go-mono.com/

1.2.1.2              性能改进

    尽管前面和Java作了比较,但是实际上中间语言(IL)比Java字节码更有野心。IL总是即时编译(被称为JIT编译),然而Java字节码常常是解释性的。像Java那样解释编译的一个缺点是,在运行时,将Java字节码翻译为本地可执行的代码这个过程导致了性能的损失(这里不包括最近新加入的Java平台,有些特定的Java平台已经实现了JIT编译)。

    并不是一次就将整个应用程序编译(那样的话导致应用程序在启动的时候变得很慢),JIT仅仅是简单的将需要用到的一部分代码编译(就像他的名字,即时编译)。当代码一旦被编译完成后,这些代码就会被作为本地可执行的结果保存下来直到应用程序退出。所以,当这一部分代码再次被调用的时候不需要再次编译。Microsoft认为这个过程的效率比一开始就编译整个应用程序的代码要高得多。因为实际上每次运行大多数部分的应用程序代码都被执行的可能性是不大的。采用这种JIT编译器,这样的代码将永远不会被编译。

       这就解释了我们为什么认为托管IL代码执行起来就像是执行本机代码一样快。但是,这并没有说明为什么Microsoft认为我们将会获得性能的提高。性能获得提高的一个原因是,当最后一个编译阶段在运行时发生时,JIT编译器已经确切的知道了程序将要运行于的处理器类型。这就意味着编译器可以优化最后的可执行代码以便利用特定处理器所带来的任何特性和特定的机器代码指令。

       传统的编译器也会优化代码,但是它仅仅是完成了与程序将要运行于的特定的处理器无关的优化。这是因为传统的编译器是在软件装载之前将源代码编译为本地执行代码的。这就意味着在编译之时编译器并不知道软件将要运行于的处理器类型,例如究竟是会运行在x86兼容处理器上还是Alpha处理器上。比如,Visual Studio 6就是针对普通的奔腾处理器作了优化,所以这也意味着它所产生的代码无法利用Pentium III处理器的硬件特性。相反,JIT除了可以完成Visual Studio 6所完成的优化工作之外,还可以针对软件将要运行于的特定处理器做优化。

1.2.1.3    语言互操作性

    IL的作用不仅仅是赋予了平台无关性,它还促进了语言互操作性。简单的说,你可以将任何一种语言的代码编译为IL,而且这个编译好了的代码可以和任何其他的语言编译成的IL进行交互。

    现在你或许想要知道除了C#之外还有什么语言可以跟.NET进行交互,是吗?好,那么就让我们简要的讨论一下究竟其他的语言是怎么使自己适合.NET.的。

Visual Basic .NET

Visual Basic 6升级到最新的Visual Basic.NETVisual Basic经历了一番彻底的改造。从最近几年Visual Basic 6的发展情况来看,它并不是一个适合运行于.NET的语言。比如,他过度的与COM集成,并且仅仅是将源代码通过事件处理的程序显示给开发人员,这样就导致源代码中的大量后置代码开发人员并不能利用。还不仅仅是如此,Visual Basic 6还不支持实现继承,而且Visual Basic 6的标准数据类型也和.NET的不兼容。

       现在,Visual Basic 6已经升级成了新的Visual Basic .NET,而且语言的变化如此知道所以你最好将Visual Basic .NET看作是一种新的编程语言。已经存在的Visual Basic 6代码现在已经不能被当作Visual Basic .NET的代码编译。如果想要将以前的Visual Basic 6代码转移到Visual Basic .NET就必须做出巨大的修改。但是Visual Studio .NET(新一代的基于.NET的VS)可以替你做这些修改中的大部分工作。如果你试图在Visual Studio .NET打开原来Visual Basic 6的工程,Visual Studio .NET就会为你升级工程,这意味着它将用Visual Basic .NE重写原来的Visual Basic 6源代码。尽管这样升级代码的繁重工作已经大大的减轻,但是你还是学要检查新产生的Visual Basic .NET代码已确定它确实是按照预期正确工作的,毕竟,这样的转换可能并不完美。

         升级后的另一个改变是Visual Basic .NET不会再被编译为本地执行代码了,相反和C#一样,他被编译为IL。也许你还是需要继续编写Visual Basic 6代码,也许你确实需要这样,你就必须在原来的Visual Studio 6进行开发,而且这样的代码也会完全忽略.NET Framework

Visual C++ .NET

         为了适应Windows,微软Visual C++ 6已经对其作了大量特定的扩展。到了Visual C++ .NET,其又被扩展以支持.NET Framework。这意味着现有的C++源代码可以不用修改的继续编译为本地可执行代码。但是,这也说明这样的本地代码和.NET运行时是没有什么关系的。如果你想要使你的C++代码运行在.NET Framework之上,你就需要在你的代码的开头简单的添加下面这一行:

  #using <mscorlib.dll>                      

       你也可以传递一个“/clr参数给编译器,这样可以设置你想编译为托管代码,编译器就会将源代码编译为IL而不是本地机器码。有趣的是在将C++编译为托管代码时,编译器会编译出一种包含内嵌本地执行码的IL。这样也就是说你可以在你的C++代码里面混用托管类型和非托管类型。像这样的托管C++代码:

       class MyClass

{  

       定义了一个普通的C++类,而下面的代码:

       __gc class MyClass

{     

       将要定义一个托管的类,就像你在C#或者Visual Basic .NET定义的类一样。托管C++代码比C#代码更好的一点是你没必要采用COM交互功能就可以直接调用非托管C++类。

         如果你试图用在托管类型上使用一个.NET并不支持的功能编译器就将报告错误(例如,模板或者多继承)。当然你也会发现当你使用托管类时你需要使用非标准C++特性(例如上面提到的关键字__gc)。

       由于C++的自由,C++允许低级指针操作等方面的特性,所以C++编译器不能生成能够通过CLR的内存类型安全测试的代码。如果通过CLR的内存类型安全测试对你的代码很重要,那么你就用其他的语言来编写你的源代码(例如C#或者Visual Basic .NET)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值