[你必须知道的.NET] 第七回:品味类型---从通用类型系统开始

发布日期:2007.5.11 作者:Anytao

©2007 Anytao.com ,原创作品,转贴请注明作者和出处。

 

本文将介绍以下内容:

  • .NET 基础架构概念 
  • 类型基础
  • 通用类型系统
  • CLI、CTS、CLS的关系简述

 

1. 引言

www.anytao.com 

 

本文不是连环画,之所以在开篇以图形的形式来展示本文主题,其实就是想更加特别的强调这几个概念的重要性和关注度,同时希望从剖析其关系和联系的角度来讲述.NET Framework背后的故事。因为,在作者看来想要深入的了解.NET,必须首先从了解类型开始,因为CLR技术就是基于类型而展开的。而了解类型则有必要把焦点放在.NET类型体系的公共基础架构上,这就是:通用类型系统(Common Type System, CTS)。

我之所以将最基本的内容以独立的章节来大加笔墨,除了为后面几篇关于对类型这一话题深入讨论做以铺垫之外,更重要的是从论坛上、博客间,我发现有很多同行对.NET Framework基础架构的几个重要体系的理解有所偏差,因此很有必要补上这一课,必备我们在深入探索知识的过程中,能够游刃有余。

2. 基本概念

还是老套路,首先引入MSDN对通用类型系统的定义,通用类型系统定义了如何在运行库中声明、使用和管理类型,同时也是运行库支持跨语言集成的一个重要组成部分。通用类型系统执行以下功能:

  • 建立一个支持跨语言集成、类型安全和高性能代码执行的框架。
  • 提供一个支持完整实现多种编程语言的面向对象的模型。
  • 定义各语言必须遵守的规则,有助于确保用不同语言编写的对象能够交互作用。

那么我们如何来理解呢?

还是一个现实的场景来引入讨论吧。小王以前是个VB迷,写了一堆的VB.NET代码,现在他变心了,就投靠C#的阵营,因为流行嘛。所以当然就想在当前的基于C#开发的项目中,应用原来VB.NET现成的东西,省点事儿:-)。那么CLR是如何来实现类型的转换的,例如Dim i as Single变量i,编译器会自动的实现将i由Single到float的映射,当然其原因是所有的.NET编译器都是基于CLS实现的。具体的过程为:CTS定义了在MSIL中使用的预定义数据类型,.NET语言最终都要编译为IL代码,也就是所有的类型最终都要基于这些预定义的类型,例如应用ILDasm.exe分析可知,VB.NET中Single类型映射为IL类型就是float32,而C#中float类型也映射为float32,由此就可以建立起VB.NET和C#的类型关系,为互操作打下基础。

.method public hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 15 (0xf)
.maxstack 1
.locals init (float32 V_0)
IL_0000: nop
IL_0001: ldc.r4 
1.
IL_0006: stloc.
0
IL_0007: ldloc.
0
IL_0008: call 
void [mscorlib]System.Console::WriteLine(float32)
IL_000d: nop
IL_000e: ret
// end of method BaseCts::Main

过去,由于各个语言在类型定义方面的不一致,造成跨语言编程实现的难度,基于这一问题,.NET中引入CTS来解决各个编程语言类型不一致的问题,类型机制使得多语言的代码可以无缝集成。因此CTS也成为.NET跨语言编程的基础规范,为多语言的互操作提供了便捷之道。可以简单的说,基于.NET的语言共同使用一个类型系统,这就是CTS。

进一步的探讨通用类型系统的内容,我们知道CTS支持两种基本的类型,每种类型又可以细分出其下级子类,可以以下图来表示:

 

.NET提供了丰富的类型层次结构,从上图中也可以看出该层次结构是基于单继承层次实现的,反映了.NET面向对象原则中实现单继承、接口多继承的特点。关于值类型和引用类型,是之后要探讨的重点内容,也是『品味类型』子系列的重中之重,在此不作进一步探讨,但是上面的这张图有必要清楚的印在心中,因为没有什么比这个更基础的了。  

3. 位置与关系

位置强调的是CTS在.NET技术框架中的位置和作用,作者期望以这种方式来自然的引出.NET技术架构的其他基本内容,从而在各个技术要点的层次中,来讲明白各个技术要点的些细联系,从大局的角度来对其有个基本的把握。我想,这样也可以更好的理解CTS本身,因为技术从来都不是孤立存在的。

.NET技术可以以规范和实现两部分来划分,而我们经常强调和提起的.NET Framwork,主要包括公共语言运行时(Common Language Runtime, CLR)和.NET框架类库(Framework Class Library, FCL),其实是对.NET规范的实现。而另外一部分:规范,我们称之为公共语言架构(Common Language Infrastructure, CLI),主要包括通用类型系统(CTS),公共语言规范(Common Language Specification, CLS)和通用中间语言(Common Intermediate Language, CIL)。我们以图的形式来看看CTS在.NET技术阵营中的位置,再来简要的介绍新登场的各个明星。

www.anytao.com 

  • CLI,.NET技术规范,已经得到ECMA(欧洲计算机制造商协会)组织的批准实现了标注化。
  • CTS,本文主题,此不冗述。
  • CLS,定义了CTS的子集,开发基于CTS的编译器,则必须遵守CLS规则,由本文开头的图中就可以看出CLS是面向.NET的开发语言必须支持的最小集合。
  • CIL,是一种基于堆栈的语言,是任何.NET语言编译产生的中间代码,我们可以理解为IL就是CLR的汇编语言。IL定义了一套与处理器无关的虚拟指令集,与CLR/CTS的规则进行映射,执行IL都会翻译为本地机器语言来执行。常见的指令有:add, box, call, newobj, unbox。另外,IL很类似于Java世界里的字节码(Bytecode),当然也完全不是一回事,最主要的区别是IL是即时编译(Just in time, JIT)方式,而Bytecode是解释性编译,显然效率上更胜一踌。
  • .NET Framework,可以说是CLI在windows平台的实现,运行与windows平台之上。
  • CLR,.NET框架核心,也是本系列的核心。类似于Java世界的JVM,主要的功能是:管理代码执行,提供CTS和基础性服务。对CLR的探讨,将伴随着这个系列的成长来慢慢展开,在此就不多说了。
  • FCL,提供了一整套的标准类型,以命名空间组织成树状形式,树的根是System。对程序设计人员来说,学习和熟悉FCL是突破设计水平的必经之路,因为其中数以万计的类帮助我们完成了程序设计绝大部分的基础性工作,重要的是我们要知道如何去使用。

可见,这些基本内容相互联系,以简单的笔墨来澄清其概念、联系和功能,显然还不够力度。然而在此我们以抛砖引玉的方式来引入对这些知识的探求,目的是给一个入口,从此来进行更深入的探索是每个设计人员的成长的关键,就像对FCL的认识,需要实践,需要时间,需要心思。 

4. 通用规则

  • .NET中,所有的类型都继承自System.Object类。
  • 类型转换,通常有is和as两种方式,具体的探讨可以参考我的另一拙作《第一回:恩怨情仇:is和as》。另外,还有另外的几个类型转换的方式:(typename)valuename,是通用方法;Convert类提供了灵活的类型转换封装;Parse方法,适用于向数字类型的转换。
  • 可以给类型创建别名,例如,using mynet = Anytao.net.MyClass,其好处是当需要有两个命名空间的同名类型时,可以清楚的做以区别,例如:
using AClass = Anytao.net.MyClass;
using BClass = Anytao.com.MyClass;

其实,我们常用的int、char、string对应的是System.Int32、System.Char、System.String的别名。

  • 一个对象获得类型的办法是:obj.GetType()。
  • Typeof操作符,则常在反射时,获得自定义类型的Type对象,从而获取关于该类型的方法、属性等。
  • 可以使用 CLSCompliantAttribute 将程序集、模块、类型和成员标记为符合 CLS 或不符合 CLS。
  • IL中使用/checked+开关来进行基元类型的溢出检查,在C#中实现这一功能的是checked和unchecked操作符。
  • 命名空间是从功能角度对类型的划分,是一组类型在逻辑上的集合。

5. 结论

类型的话题,是个老掉牙的囫囵觉,但也是个永不言退的革命党。在实际的程序设计中,我们经常要吃这一亏。因为,很多异常的产生,很多性能的损耗,很多冗余的设计都和类型解下不解之缘,所以清晰、清楚的了解类型,没有什么不可以。重要的是,我们以什么角度来了解和化解,内功的修炼还是要从内力开始。本系列不求包罗万象,但求以更新鲜、更全面的角度,清楚、干净、深入的把某个问题说透,此足尹。

品味类型,就从CTS开始了。  

 

参考文献

(USA)Jeffrey Richter, Applied Microsoft .NET Framework Programming

(USA)David Chappell, Understanding .NET

广而告之

[预告]

简要的探索了CTS的基本知识和几个关系,我们将要把笔墨着重在对类型的深入探索上,近期本系列就以类型这一话题为核心来了解以下几个相关主题:值类型和引用类型,装箱与拆箱,强类型等。这些概念和技术都是.NET基本知识中最重要的内容,我将通过自己的视角和观点来揭开类型概念中的重要知识点,层层深入、循序渐进的打开通向.NET更深层次的大门。

所以,本文是个铺垫,下回会更精彩和期待。  

温故知新

[开篇有益]

[第一回:恩怨情仇:is和as]

[第二回:对抽象编程:接口和抽象类]

[第三回:历史纠葛:特性和属性]

[第四回:后来居上:class和struct]

[第五回:深入浅出关键字---把new说透]

[第六回:深入浅出关键字---base和this]

©2007 Anytao.com

原创作品,转贴请注明作者和出处,留此信息。

本贴子以现状提供且没有任何担保,同时也没有授予任何权利。
This posting is provided "AS IS" with no warranties, and confers no rights.

posted @ 2007-05-11 00:13 Anytao 阅读(7841) 评论(36)  编辑 收藏 网摘 所属分类: 01 [你必须知道的.NET]

  回复  引用    
#2楼2007-05-11 09:53 | 西门子乌[未注册用户]
好文章,标题也很有噱头。
  回复  引用  查看    
#3楼2007-05-11 13:47 | Terry Sun      
如果没记错的话LZ在文中提到的CRL应该是CLR吧--Common Language Runtime
  回复  引用  查看    
#4楼[楼主]2007-05-11 15:59 | Anytao      
@.net开发资源精华收集
感谢支持,继续努力。

  回复  引用  查看    
#5楼[楼主]2007-05-11 16:01 | Anytao      
@西门子乌
@荔树人家
感谢支持,继续努力,重要的是内容,呵呵。

  回复  引用  查看    
#6楼[楼主]2007-05-11 16:06 | Anytao      
@Terry Sun
笔误,马上更正,谢谢了。

  回复  引用  查看    
#7楼2007-05-12 09:56 | 学海无涯,回头是岸      
好文啊

.NET框架类卡
应该是类库吧

  回复  引用  查看    
#8楼[楼主]2007-05-12 10:43 | Anytao      
@学海无涯,回头是岸
太粗心了,还是笔误,更正了。非常感谢。

  回复  引用  查看    
#9楼2007-05-14 11:46 | Anders Liu      
第二部分,图的下面:
“从上图中也可以看出该层次结构是基于单继承层次实现的,”

我即得在某微软文档中看到过这张图,其下面着重说了一句:不要将这张图和类继承层次混淆。

换句话说,这张图只介绍了类型系统中各种类型的类型的关系,而不能表达各种类型之间的关系(这句话我也说不清楚,看各位是否能理解了~ :))

  回复  引用  查看    
#10楼[楼主]2007-05-14 12:35 | Anytao      
你所言甚是,此处表达的意思是该结构可以反映出单继承性,而不是用来说明类的层次结构关系,这显然是两个概念。谢谢你的指正。另外,本系列中所有引用外部的图都没有加入©2007 Anytao.com标记。
  回复  引用  查看    
#12楼[楼主]2007-05-28 13:51 | Anytao      
@snowdoggie
很抱歉, 太粗心了, 一定更改.

  回复  引用  查看    
#13楼[楼主]2007-05-28 14:02 | Anytao      
@念时
感谢支持.

  回复  引用  查看    
#14楼2007-09-21 09:12 | 最后一滴血      
每天多来一点,每天多学一点
  回复  引用  查看    
#15楼[楼主]2007-09-26 11:17 | Anytao      
@最后一滴血
呵呵,我也是,博客园是个能够成长的地方。

  回复  引用  查看    
#16楼2007-09-29 10:42 | 镜涛      
不知道微软那本CLR的书对这方面介绍的怎样!楼主可否给点建议啊!谢了
  回复  引用  查看    
#17楼[楼主]2007-09-29 14:14 | Anytao      
@镜涛
镜涛兄是否指的是,这本Jeffrey Richter, Applied Microsoft .NET Framework Programming,很多人都推荐这本.NET领域的圣经,我当然也不例外,对研究CLR基础来说Jeffrey Richter和Don Box绝对堪称专家了,也各自贡献了一部经典,Applied Microsoft .NET Framework Programming就是其中之一。在类型部分,该书中也有较深入的讨论,虽然限于篇幅很多部分并非详实,但是从大局角度已经算是尽心尽力了。
:-)

  回复  引用  查看    
#18楼2007-10-19 15:48 | 缘易姿姿      
"其实,我们常用的int、char、string对应的是System.Int32、System.Char、System.String的别名。"
---------------
那么这些别名是在哪里定义的呢?


  回复  引用  查看    
#19楼[楼主]2007-10-19 17:37 | Anytao      
@缘易姿姿
int、char、string是C#定义的基元类型的别名,对应于CTS中定义的System.Int32、System.Char、System.String类型,C#编译器在进行编译时要将C#代码翻译成MSIL代码,C# compiler会自动加上using int = System.Int32来完成这一操作。

  回复  引用    
#20楼2008-06-18 20:36 | kevinli[未注册用户]
anytao老师:
你好:
你在书上的这句话我感觉很神秘:

"CLS,定义了CTS的子集,开发基于CTS的编译器,则必须遵守CLS规则"

你意思说我们也可以做一个C#代码编译器吗?也就是说做一个简单的编辑环境像(VS2005)带编译按钮的.要是有的话,可否做个最简单的给我看下.那就太谢谢了!

liyangguang2052@126.com

  回复  引用  查看    
#21楼[楼主]2008-06-18 22:57 | Anytao      
@kevinli
感谢你的仔细阅读。

从理论上来说,你的确可以基于CLS开发出属于自己的轻量型编译器,也就是你说的类似于VS的编译环境,不过做这样的东西需要花点时间来了解和深入。限于时间和精力等方面的原因,很抱歉现在还无法满足你的需求,如何万事具备的时候,我可能也有这样的兴趣来玩玩看。

当然,也有取巧的办法来实现,那又是另外一回事儿了,有兴趣可以在这方面研究研究。其实用c#语言就可以实现一个轻量型的编译器,有时间可以研究研究CodeDom原理,一定也会有所收获。

  回复  引用    
#22楼2008-06-19 09:06 | kevinli[未注册用户]

感谢Anytao老师对问题及时的回复和方向的指导,我的意思就是用C#来编写一个轻量型的编译器,希望老师以后在百忙的时间里,抽点时间做一个C#写的简单的样例(时间上不着急),因为你的书我还没看完.也许是你潜移默化的影响,对底层挺感兴趣的(犹如雾中探路,朦胧而又不乏刺激).所以对这个例子期待中!

  回复  引用  查看    
#23楼[楼主]2008-06-19 23:51 | Anytao      
@kevinli
呵呵,谢谢你的关注。编译器是个负责的话题,涉及到例如词法分析等很多因素,有时间的时候我也很有兴趣探讨探讨,有成果的时候一定第一时间在博客园接收拍砖,还望关注:-)
再次感谢

  回复  引用  查看    
#24楼2008-09-26 18:46 | 棠棠dotNet      
强烈支持LZ,感觉比看其书还清晰。
  回复  引用  查看    
#25楼2009-02-19 15:17 | feisky      
这几天一直在看你的这个系列 收获不小
  回复  引用  查看    
#26楼[楼主]2009-02-20 00:52 | Anytao      
@棠棠dotNet
呵呵,谢谢。

  回复  引用  查看    
#27楼[楼主]2009-02-20 00:52 | Anytao      
@feisky
希望继续关注,因为我也一直在努力:-)




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 742317




相关文章:

相关链接: