展现C#word版.docx

上传人:b****5 文档编号:30054501 上传时间:2023-08-04 格式:DOCX 页数:115 大小:96.94KB
下载 相关 举报
展现C#word版.docx_第1页
第1页 / 共115页
展现C#word版.docx_第2页
第2页 / 共115页
展现C#word版.docx_第3页
第3页 / 共115页
展现C#word版.docx_第4页
第4页 / 共115页
展现C#word版.docx_第5页
第5页 / 共115页
点击查看更多>>
下载资源
资源描述

展现C#word版.docx

《展现C#word版.docx》由会员分享,可在线阅读,更多相关《展现C#word版.docx(115页珍藏版)》请在冰豆网上搜索。

展现C#word版.docx

展现C#word版

展现C#

 第一章C#简介

 欢迎您加入C#的世界!

这一章将把您引进C#的天地,并回答一些相关的问题,如:

您为什么要使用C#,C++和C#的主要有什么不同点,以及为什么C#使开发更容易而且还使您感到很有趣。

为什么是另外一种编程语言?

 必须回答的一个问题:

当您已经使用C++或VB从事企业开发时,为什么还要学习另一种语言?

市场式的回答就是:

"在企业计算领域,C#将会变成为用于编写"下一代窗口服务"(NextGenerationWindowsServices,简写为NGWS)应用程序的主要语言。

这一章将对用参数请求提供支持,并陈列了C#的一些功能。

这一章会使您开胃的。

 C#语言自C/C++演变而来。

但是,它现代、简单、完全面向对象和类型安全。

如果您是C/C++程序员,学习曲线将会很平坦。

许多C#语句直接借用您所喜爱的语言,包括表达式和操作符。

假如不仔细看,简直会把它当成C++。

 关于C#最重要的一点:

它是现代的编程语言。

它简化和现代化了C++在类、名字空间、方法重载和异常处理等领域。

屏弃了C++的复杂性,使它更易用、更少出错。

 对C#的易用有贡献的是减少了C++的一些特性,不再有宏、模板和多重继承。

特别对企业开发者来说,上述功能只会产生更多的麻烦而不是效益。

 使编程更方便的新功能是严格的类型安全、版本控制、垃圾收集(garbagecollect)等等。

所有的这些功能的目标都是瞄准了开发面向组件的软件。

 在继续呈现出更多的功能之前,我想停下来并在下面说明C#至关重要的各种要素。

简单

现代

面向对象

类型安全

版本控制

兼容

灵活

简单

 C#具有C++所没有的一个优势就是学习简单。

该语言首要的目标就是简单。

很多功能(还不如说是缺少了C++的一些功能)有助于C#全方位的简单。

 在C#中,没有C++中流行的指针。

默认地,您工作在受管理的代码中,在那里不允许如直接存取内存等不安全的操作。

我想没有C++程序员可以声称,从没有使用指针访问过不属于他们的内存。

 与指针"戏剧性"密切相关的是"愚蠢的"操作。

在C++中,有:

:

、.、和->操作符,它们用于名字空间、成员和引用。

对于新手来说,操作符至今仍是学习的一道难关。

C#弃用其它操作符,仅使用单个操作符"."。

现在一个程序员所需要理解的就是嵌套名字的注解了。

 您不必记住基于不同处理器架构的隐含的类型,甚至各种整型的变化范围。

C#使用统一的类型系统,屏弃了C++多变的类型系统。

这种系统充许您把各种类型作为一个对象查看,它是一个原始类型还是一个full-blown类。

和其它编程语言相比,由于加框(boxing)和消框(unboxing)的机制,把简单类型当作对象处理并不能获得性能的改善。

稍后将详细解释加框和消框,但基本上仅当需要时才使用对象访问简单类型这种技术。

 首先,老练的程序员可能不喜欢它,但是整型和布尔型如今终归是两种完全不同的数据类型。

这就意味着原来if语句中错误的赋值现在会被编译出错,因为if语句只接受布尔类型的值。

再也不会出现误用赋值符为比较符这样的错误!

  C#同时也解决了存在于C++中已经有些年头的多余东西(redundancies)。

这种多余包括常数预定义,不同字符类型等。

鉴于多余表单已经从该语言中消失,故一般在C#中都可以使用简单了。

现代

 您投入学习C#的努力是一笔大投资,因为C#是为编写NGWS应用程序的主要语言而设计。

您将会发现很多自己用C++可以实现或者很费力实现的功能,在C#中不过是一部分基本的功能而已。

 对于企业级的编程语言来说,新增的金融数据类型很受欢迎。

您用到了一种新的十进制数据类型,它专用于金融计算方面。

如果不喜欢这种现成简单的类型,根据您应用程序的特殊需求,可以很容易地创建出新的一种数据类型。

 我已经提到,指针不再是您编程武器的一部分。

不要太惊讶,全面的内存管理已经不是您的任务。

运行时NGWS提供了一个垃圾收集器,负责C#程序中的内存管理。

因内存和应用程序都受到管理,所以很必要增强类型安全,以确保应用的稳定性。

 对于C++程序员,异常处理的切不是新的东西,但它是C#的主要功能。

C#的异常处理与C++的不同点在于它是交叉语言的(运行时的另一个功能)。

在没有C#之前,您必须处理怪异的HRESULTs,但现在由于使用了基于异常的健壮的出错处理,这一切都结束了。

 对于现代的应用程序,安全是首要的,C#也不会例外。

它提供了元数据语法,用于声明下述NGWS安全模式的能力和许可。

元数据是NGWS运行时的一个关键的概念,下一章将涉及到它更深的含义。

面向对象

 您不会预料一种新语言不支持面向对象的功能吧?

C#当然支持所有关键的面向对象的概念,如封装、继承和多态性。

完整的C#类模式构建在NGWS运行时的虚拟对象系统(VOS,VirtualObjectSystem)的上层,VOS将在下章描述。

对象模式只是基础的一部分,不再是编程语言的一部分。

 您一开始必须关注的事,就是不再有全局函数、变量或者是常量。

所有的东西都封装在类中,包括事例成员(通过类的事例--对象可以访问)或都静态成员(通过数据类型)。

这些使C#代码更加易读且有助于减少潜在的命名冲突。

 定义类中的方法默认是非虚拟的(它们不能被派生类改写)。

主要论点是,这样会消除由于偶尔改写方法而导致另外一些原码出错。

要改写方法,必须具有显式的虚拟标志。

这种行为不但缩减速了虚拟函数表,而且还确保正确版本的控制。

 使用C++编写类,您可以使用访问权限(accessmodifiers)给类成员设置不同的访问等级。

C#同样支持private、protected和public三种访问权限,而且还增加了第四种:

internal。

有关访问权限的详细情况将在第五章"类"中说明。

 您曾经创建了多少个类是从多基类派生出来的(ATL程序员,您的投票不计在内!

)?

大多数情况,仅需从一个类派生出。

多基类惹出的麻烦通常比它们解决的问题还多。

那就是为什么C#仅允许一个基类。

如果您觉得需要多重继承,可以运用接口。

 一个可能出现的问题:

在C#中不存在指针,如何模仿它?

这个问题的答案很有代表性,它提供了对NGWS运行时事件模式的支持。

再次,我将把对它的全面解释放到第五章。

类型安全

 我再次选指针作为一个例子。

在C++中拥有一个指针,您能自由地把它强制转换成为任何类型,包括干出诸如把一个int*(整型指针)强制转换成一个double*(双精度指针)这样的傻事。

只要内存支持这种操作,它就"干过"。

这并不是您所想象的企业级编程语言的类型安全。

 纲要性的问题,C#实施最严格的类型安全,以保护自己及垃圾收集器(garbagecollector)。

所以必须遵守C#中一些相关变量的规则:

 不能使用没有初始化的变量。

对于对象的成员变量,编译器负责清零。

而局部变量,则由您负责清零。

当您使用一个没有初始化的变量时,编译器会教您怎么做。

优点是能够避免由于使用不经初始化的变量计算结果而导致的错误,而您还不知道这些奇怪的结果是如何产生的。

 C#取消了不安全的类型转换。

不能把一个整型强制转换成一个引用类型(如对象),而当向下转换时,C#验证这种转换是正确的。

(也就是说,派生类真的是从向下转换的那个类派生出来的。

 边界检查是C#的一部分。

再也不会出现这种情况:

当数组实际只定义了n-1个元素,却超额地使用了n个元素。

 算术运算有可能溢出终值数据类型的范围。

C#允许在语句级或应用程序级检测这些运算。

在允许检测溢出的情况下,当溢出发生时将会抛出一个异常。

 在C#中,被传递的引用参数是类型安全的。

版本可控(Versionable)

 在过去的几年中,几乎所有的程序员都至少有一次不得不涉及到众所周知的"DLL地狱"。

该问题起因于多个应用程序都安装了相同DLL名字的不同版本。

有时,老版本的应用程序可以很好地和新版本的DLL一起工作,但是更多的时候它们会中断运行。

现在的版本问题真是令人头痛。

 就象您将在第八章"用C#写组件"所看到的,NGWSruntime将对您所写的应用程序提供版本支持。

C#可以最好地支持版本控制。

尽管C#不能确保正确的版本控制,但是它可以为程序员保证版本控制成为可能。

有这种支持,一个开发人员就可以确保当他的类库升级时,仍保留着对已存在的客户应用程序的二进制兼容。

兼容

 C#并没有存在于一个封闭的世界中。

它允许使用最先进的NGWS的通用语言规定(CommonLanguageSpecification,简写为CLS)访问不同的API。

CLS规定了一个标准,用于符合这种标准的语言的内部之间的操作。

为了加强CLS的编译,C#编译器检测所有的公共出口编译,并在通不过时列出错误。

 当然,您也想能够访问旧一点的COM对象。

NGWS运行时提供对COM透明的访问。

如何集成原来的代码将在第10章"非管理代码的内部操作"有介绍。

 OLE自动化是一种特殊的动物。

任一个使用C++创建OLE自动化项目的人已经喜欢上各种各样的自动化数据类型。

有个好消息就是C#支持它们,而没有烦锁的细节。

 最后,C#允许您用C原型的API进持内部操作。

可以从您的应用程序访问任何DLL中的入口点(有C的原型)。

用于访问原始API的功能称作平台调用服务(PlaformInvocationServices,缩写PInovke),第10章将展示使用CAPI进行内部操作的一些例子。

灵活

 上一部分的最后一段有可能提醒了程序员。

您可能会问:

"难道就没有我要传递指针的API吗?

"您是正确的。

不是仅有少数的这种API,而是很多(有点保守的估计)。

这种对原始WIN32代码的访问有时导致对非安全类指定指针的使用(尽管它们中的一些由于受COM和PInvoke的支持可以解决)。

 尽管C#代码的缺省状态是类型安全的,但是您可以声明一些类或者仅声明类的的方法是非安全类型的。

这样的声明允许您使用指针、结构,静态地分配数组。

安全码和非安全码都运行在同一个管理空间,这样暗示着当从安全码调用非安全码时不会陷入列集(marshaling)。

小结

 C#语言从C和C++演变而来,它是给那些愿意牺牲C++一点底层功能,以获得更方便和更产品化的企业开发人员而创造的。

C#现代、简单、面向对象和类型安全。

尽管它借鉴了C和C++的许多东西,但是在一些诸如名字空间、类、方法和异常处理等特定领域,它们之间还存在着巨大的差异。

 C#为您提供了方便的功能,如垃圾收集、类型安全、版本控制,等等。

仅有的"代价"就是,代码操作默认是类型安全的,不允许指针。

光是类型安全就可以搞定了。

但是,如果您需要指针,仍可以通过非安全码使用它们,而且当调用非安全码时,不能含有列集。

*使用这本书你需要什么?

从这本书的观点看,你所需要的就是下一代windows服务软件开发包(NGWSSDK)。

尽管至少只要有NGWSRuntime和C#编译器就可以,但当探索这些激动人心的新技术功能时,在一台机器上装有说明文件档和所有的SDK工具(包括debugger),将是一个极好的主意。

这本书不需要你装在机器上的VisualStudio7的任何工具。

我仅建议你要有一个优秀的支持行数的程序编辑器,用以编辑C#源文件。

《展现C#》第二章NGWSRuntime技术基础(rainbow译)

 内  容:

 第二章NGWSruntime技术基础

既然你已经具有了C#全面的印象,我也想让你了解NGWSruntime的全貌。

C#依靠由NGWS提供的运行时;因此,有必要知道运行时如何工作,以及它背后所蕴含的概念。

所以,这一章分为两部分——它们是所有的概念和使用的基础。

两部分的内容虽然有些重叠,但它有助于加深理解正在学习的概念。

2.1NGWSRuntime

NGWS和NGWSRuntime为你提供了一种运行时环境。

该运行时管理执行代码,并提供了使编程更容易的服务。

只要你的编译器支持这种运行时,你就会从这种受管理的执行环境中得益。

你猜测C#编译器支持NGWSruntime很正确,但是不仅它支持NGWSruntime,VB和C++也支持。

这些为支持运行时所创建的代码称作"受管代码"(managedcode)。

以下是你的应用程序从NGWSruntime那里所得到的利益:

交叉语言集成(通过通用语言规范)

自动内存管理(垃圾收集)

交叉语言异常处理(统一展开)

增强安全(包括类型安全)

版本支持("DLL地狱"终结者)

组件交互简化模式

因NGWSruntime要提供了所有的这些好处,编译器必须把元文件和受管代码一起发出。

元文件描述代码中的类型,它和你的代码存在一起(与PE类似---PE为可变位执行文件)

正如你从很多种交叉语言功能所看到的,NGWSruntime主要是关于高度集成交叉多异编程语言(tightintegrationacrossmultipledifferentprogramminglanguages)。

这种支持可达到允许你从一个VB对象派生出一个C#类的程度(我后面会给出要讨论的文章)。

C#程序员将会喜欢的一个功能是,他们不必担心内存管理—也就是说不必担心臭名昭著的内存泄漏。

NGWSruntime提供了内存管理,当对象和变量的生命期结束(不再被引用)时,垃圾收集器释放它们。

我真的喜欢这个功能,因为在COM中的内存管理一直是我的一块心病。

应该鼓励配置一个管理应用程序或者组件。

因为管理应用程序含有元数据文件,NGWSruntime可以利用这些信息,以确保你的应用程序具有它所需的各种规定版本。

所产生的明显效果为,由于你的代码没有相互之间的依赖,很少可能出现中断。

这章余下来的将分为两部分,每一部分讨论NGWSruntime的各个方面,直到你的C#应用程序能执行为止。

1、中间语言(IntermediateLanguage,缩写IL)和元数据

2、即时编译器(just-in-timecompliers,简称JITers)

2.1.1中间语言和元数据

由C#编译器生成的受管代码并不是原始代码,但它是中间语言(IL)代码。

这种IL代码自身变成了NGWSruntime的受管执行进程的入口。

IL代码明显的优势在于它是CPU无关的,这也意味着,你要用目标机器上的一个编译器才能把IL代码转换成原始代码。

尽管IL代码由编译器产生,但它并不是编译器提供给运行时仅有的东西。

编译器同样产生有关你代码的元数据,它告诉运行

时有关你代码的更多的东西,例如各种类型的定义、各种类型成员的签名以及其它数据。

基本上,元数据是类型库、注册表内容和其它用于COM的信息。

尽管如此,元数据还是直接和执行代码合并在一起,并不处在隔离的位置。

IL和元数据存放于扩展了PE格式的文件中(PE格式用于.exe和.dll文件)。

当这样的一个PE文件被装载时,运行时从文件中定位和分离出元数据和IL。

在进一步说明之前,我想给你已有的IL指令的简短目录。

尽管它不是一个完整的清单,也不需要你熟记和理解,但是它列出了你所必需的、C#程序所基于的知识基础。

算术和逻辑操作符

控制流

直接内存访问

堆栈操作

参数和局部变量

堆栈分配

对象模式

实例类型值

临界区

数组

分型位置

即时编译器(JITters)

2.1.2即时编译器(JITters)

由C#或其它能产生受管代码的编译器所生成的受管代码就是IL码。

虽然IL代码被包装在一个有效的PE文件中,但是你还是不能执行它,除非它被转换成为受管原始代码。

这就是NGWSruntime即时编译器(也称作JITters)大显身手的时候。

为什么你会对即时编译代码感到厌繁,为什么不把整个ILPE文件编译成原始代码?

答案是时间——需要把IL代码编译成CPU规格的代码的时间。

这种编译将更加有效率,因为一些程序段从来就没有被执行过。

例如,在我的字处理器中,邮件合并功能从来就没有被编译。

从技术上说,全部的处理过程如下:

当一个类型被装载时,装载器创建一个存根(stub),并使它连接每一个类型的方法。

当一个方法第一次被调用时,存根把控制交给JIT。

JIT把IL编译为原始代码,且把存根指针指向缓冲了的原始代码。

接着的调用将执行原始码。

在某些位置上(Atsomepoint),所有的IL都被转换成为原始代码,而JITter处于空闲状态。

用的JIT编译器。

它是一个后台(backend)优化的编译器,在前台(upfront)实行数据流分析,并创建了高度优化的受管原始代码做为输出结果。

JIT可以使用不严格的IL指令集编码,但是所需资源将十分可观。

主要的限制在于内存足迹(footprint)、结果工作集,以及实行优化所消耗的时间。

EconoJIT——和主JIT相比,EconJIT的目标是把IL高速地转换成受管原始代码。

它允许缓冲所产生的原始代码,但是输出码并不象主JIT生成的代码那样优化(代码小)。

当内存紧张时,快速代码生成方案的优势将荡然无存。

通过永久地抛弃无用的已JIT过的代码,你可以把更大的IL程序装入代码缓冲区。

因为JIT编译快,执行速度也仍然很快。

PreJIT—尽管它是基于主JIT的,但操作起来更象是一个传统的编译器。

你安装了NGWS组件,它才能运行,才可以把IL代码编译成受管原始代码。

当然最终的结果为,更快的装载时间和更快的应用程序启动时间(不需要更多的JIT编译)。

在所列出的JITters中,有两个是运行时的JITters。

可是你怎么决定要使用哪一个JIT,它如何使用内存?

有一个称做"JIT编译管理器"的小应用程序(jitman.exe),它存放于NGWSSDK安装目录下的bin目录中。

当执行该程序时,它把一个图标加到系统任务条上,双击该图标打开程序对话框(见图2.1)。

图2.1JIT编译管理器允许你设置各种相关性能的选项

尽管它是一个小小的对话框,可是你所选择的选项功能是相当强大的。

每一个选项将在以下描述。

UseEconoJITonly选项——当该复选框没有选上时,NGWSruntime使用默认的正常的JIT编译器。

前面就曾经解释过两种JITter的区别。

MaxCodePitchOverhead(%)选项——该设置仅保留给EconoJIT。

它控制了JIT编译时间和执行代码时间的百分比。

如果超过了设定的域值,代码缓冲区得到扩充,以缩短JIT编译所消耗的时间。

LimitSizeofCodeCache选项——该项默认为非选。

没有选择该项意味着缓冲区将使用它所能得到的内存。

如果你想限制缓冲区大小,复选该选项,这将允许你使用MaxSizeofCache(bytes)选项。

MaxSizeofCache(bytes)选项—控制容纳JIT代码的缓冲区的最大值。

虽然你可以非常严格地限制这个值,但你还是应该小心,不能超过这个缓冲区所适合的最大值。

否则该方法的JIT编译将会失败。

OptimizeForSize选项——告诉JIT编译器,优化的目的是为了使代码更小而不是能执行得更快。

这个设置默认是关掉的。

EnableConcurrentGC[garbagecollection]选项——垃圾收集(GC)默认地运行在用户代码的线程中。

意味GC发生时,可能会注意到回应有轻微的延迟。

为防止出现该现象,打开当前GC。

注意,当前GC比标准GC更慢,它仅在windows2000上写时(thetimeofwriting)有效。

当用C#创建项目时,你可能使用不同的设置试验过。

当创建UI-intensive应用程序时,你将会看到允许当前GC的最大差别。

2.2虚拟对象系统(VOS)

到目前为止,你仅看到了NGWSruntime如何工作,但是并不了解它工作的技术背景以及为什么它要这样工作。

这节都是关于NGWS虚拟对象系统的(VOS)。

以下为在VOS中形成声明、使用和管理类型模型时,NGWSruntime的规则。

在VOS背后的思想是建立一个框架,在执行代码时不能牺牲性能,允许交叉语言集成和类型安全。

我提到的框架是运行时架构的基础。

为了帮助你更好地了解它,我将它勾出四个区域。

当开发C#应用程序和组件时,理解它们很重要。

VOS类型系统——提供丰富的类型系统,它打算支持全面编程语言的完全实施。

元数据——描述和引用VOS类型系统所定义的类型。

元数据的永久格式与编程语言无关,但是,元数据拿自己当作一种互换机制(nterchangemechanism)来使用,这种互换是在在工具和NGWS的虚拟执行系统之间。

通用语言规范(CLS)——CLS定义了VOS中类型的子集,也定义了常规的用法。

如果一个类库遵守CLS的规则,它确保类库可以在其它所有能实现CLS的编程语言上使用。

虚拟执行系统(VES)——这是VOS实时的实现。

VES负责装入和执行为NGWS运得时编写的程序。

这四个部分一起组成了NGWSruntime架构。

每一部分在下面小节中描述。

2.2.1VOS类型系统

VOS类型系统提供丰富的类型系统,它打算支持多种编程语言的完全实施。

所以,VOS必须都支持面向对象的语言和过程编程语言。

现在,存在着很多种近似但有点不兼容的类型。

就拿整型当例子,在VB中,它是16位长,而在C++中,它是32位。

还有更多的例子,特别是用在日期和时间以及数据库方面的数据类型。

这种不兼容使应用程序的创建和维护不必要地复杂化,尤其当程序使用了多种编程语言时。

另一个问题是,因为编程语言之间存在着一些差别,你不能在一种语言中重用另一种语言创建的类型。

(COM用二进制标准接口部分地解决了这个问题)。

当今代码重用肯定是有限的。

发布应用程序的最大障碍是各种编程语言的对象模型不统一。

几乎每一方面都存在着差异:

事件、属性、永久保存(persistence)等等。

VOS这里将改变这种现象。

VOS定义了描述值的类型,并规定了类型的所有值所必须支持的一条合约。

由于前面提到的支持面向对象和过程编程语言,就存在着两种值和对象。

对于值,类型存储于表述(representation)中,同样操作也在其中实行。

对象更强大因为它显式地存于表述中。

每一个对象都有一个区别于其它对象的识别号。

支持不同的VOS类型在第四章"C#类型"中提出。

2.2.2元数据

尽管元数据用于描述和引用由VOS类型系统定义的类型,但它还不能锁定到这个单个目标。

当你写一个程序时,通过利用类型声明,你所声明的类型(假定它们是数值类型或引用类型)被介绍给NGWSruntime类型系统。

类型声明在存于PE可执行文件内部的元数据中得到描述。

基本上,元数据用于各项任务:

用于表示NGWSruntime用途的信息,如定位和装载类、内存中这些类的事例、解决调用、翻译IL为原始码、加强安全并设置运行时上下文边界。

你不必关心元数据的生成。

元数据是由C#的"代码转IL编译器"(code-to-ILcompiler,不是JIT编译器)生成的。

代码转IL编译器发送二进制元数据信息给PE文件,是以标准的方式发送的,不象C++编译器那样,为出口函数创建它们自己的修饰名字。

你从元数据和可执行代码并存所获得的主要优势为,有关类型的信息同类型自身固定在一起,不会遍布很多地方。

同样有助于解决存在于COM中的版本问题。

进一步地,你可以在相同的上下文中使用不同的版本库,因为库不仅被注册表引用,也被包含在可执行代码中的元数据引用。

2.2.3通用语言规范

通用语言规范(CLS)并不是虚拟对象系统(VOS)真正的一部分

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1