C#语言基础原理及优缺点

一、原理:

C#是专门为.net程序框架而创造的语言。

.net框架有ms.netFramework;Mono.NetFramework(也是符合.net IL语言,CTS规范,CLS规范, CLR运行时库)mono程序可以运行在各种操作系统和游戏平台中运行(目前mono还不够成熟影响力较小)

.net原理主要是编译的原理: IL中间语言(CTS,CLS规范, 语言互调用, CLR运行时环境(.net虚拟机加载程序集编译为机器语言,内存管理(分配和回收),事件框架机制分段执行机制,应用程序域创建和组件通信,代码安全性检查和异常处理)。

.net程序组成体系主要概念:应用程序集,应用程序域。

.net程序编译过程:

1)编译时:.netvs或mono编译器(或其它编译器)将源代码(C#,VB,托管C++,J#,JScript,调用的底层C/C++代码COM)编译为编译器定义的中间语言IL

2) 运行时: CLR(.net或mono实现的)把IL语言用JIT(按需即时编译)为平台上专用的机器代码,把JIT编译好的机器代码存储起来,下次运行这部分代码时候就不用编译了。

所以需要把.net运行库(CLR一整套代码)安装到需要运行.net 程序的机器中才能运行程序。

.net中的语言都是符合.net规范的,比如 强类型,单继承,分号等比较大致的规定,语言本身细节没有太多苛刻要求。

.net程序编译和执行过程中的流程图:



二、优点及原理细节:

1. 强大的.Net Framework托管代码集合类, 封装了大多数windows上使用的技术组件类, 文件系统,UI界面,数据源访问,网络访问,COM互操作(图形图像多媒体,WPF图形系统),没有的可以通过.net的平台调用win API函数来得到。

2. 较简单的语言特性:自动内存管理, 单继承,支持事件、委托、属性、Linq等一系列让业务开发更简单的功能。

3. Web应用程序开发速度快(.net框架的支持,控件可以拖拉(UI方便编辑和定位),添加事件(跳转到控制逻辑层),ADO.net数据源访问, xml 网络类库, windows服务)。

Web窗体:System.Web.UI.WebControls.WebControl类。

XML Web服务,客户端请求,服务端返回xml 而不是html 的.net页面。

Window服务:System.ServiceProcess命名空间中的.net基类,可以支持很多window服务先关的事情。

桌面应用开发,window窗体:System.Windows.Forms.Control,.net 3.0中中的WPF。

4. 和语言平台无关的编译机制,及较快的运行速度(ms不推荐, mono Xamarin, Unity还不错):编译成IL中间语言CLR公共语言运行库托管代码,CLR根据运行时程序需要将IL中间语言用JIT即时编译方式编译为内部机器代码,对编译好的机器代码缓存起来,提高了程序速度。

.net中的所有托管语言都是使用这样的编译机制,即javascript在.net中是编译型的,而不是解释型编译的。托管的C++可以调用非托管的C++,但.net中对C++有限制不能使用模板或类的多继承,且要启用指针还需要对项目指定为CLR内存类型是非安全的。.net组合了COM的互操作性,因此托管代码可以调用COM组件,COM组件也可以调用托管代码。

平台无关:ms .net用IL和CLR理论可以做到但是实际不能跨平台的,mono是跨平台的.net 实现但影响力较小。

语言之间交互:

COM: COM是基于二进制通信的,调用方(客户程序)可以用COM运行库实例化需要的COM对象,然后通过COM对象指针来调用需要的方法或属性。组件和组件之间只通过COM运行库来通信(相互实例化)有局限(不过耦合度更底),COM不允许客户程序继承实现COM类,COM对不同的语言只能单独的调试。

IL和CLR: 利用.net编译器,编译为统一的中间代码(CLR规范), 比二进制更高一层,使得语言之间的交互更加灵活。

不同语言的类可以继承(继承),一个语言可以包含另一个语言的实例(关联组合聚合)对象可以在方法之间传递(依赖)可以相互处理异常的抛出(定义了统一的.net类来表示异常),可以调试不同语言编写的源代码。

IL中间语言规范:

中间语言的主要特性:面向对象和使用接口,值类型和引用类型间巨大差别,强数据类型,使用异常类来统一处理各语言中的异常,使用特性。

中间语言的这些规范的好处:

语言互操作,垃圾回收,安全性,应用程序域的实现

语言互操作:

数据存储的规范:引用类型总是存储在托管堆的内存区域中,值类型一般存储在栈中。

数据类型规范:强数据类型,必须明确一个变量或常量的类型,不能使用variant, 指针在标记了的C#中(非内存安全)或托管C++(非内存安全)中可以使用。

CTS(通用类型系统): 所有托管语言定义的类型,都会编译为中间语言定义的通用类型;VB中整型,C#中的int 都会被编译映射为int32, 这样不同的语言通过CTS就可以相互继承,关联组合,依赖实现通信。类型分为值类型和引用类型,值类型(内置,枚举,用户定义的值类型),引用(接口,指针,自我描述), 自我描述(数组,类), 类(用户定义的类,委托,装箱值类型)。

CLS(公共语言规范): CLS是一个最低语言规范标准集,例如CLS指定不使用任何只是根据大小写区分的名称(不区分大小写的语法),以前的VB代码就可以和CLS兼容代码一起使用,可以定制编译选项(支持部分的CLR特性的编译器编写,语言之间的相互通信)。


垃圾回收器(GC):COM是用引用计数,AddRef计数加1,Release计数减1且到0时候释放内存(还是需要手动的Release内存)。.net中是采用垃圾回收器,当.net运行库CLR检测到给定进程的托管堆已满,需要清理时,就调用垃圾回收器,检查所有托管堆中对象的引用,对引用为0的对象则清理内存。

注意:在引用环中长期持有会导致内存占用泄露,例如放置到全局或静态容器中的对象,数据库或网络链接中的对象池等。

     CLR垃圾回收器调用是不确定的,所以对于内存开销比较大的程序逻辑,需要手动在代码中调用垃圾回收器。

           C#中也可以显示的调用析构函数,可以方便的释放内存资源。


代码安全性:window是基于角色的安全机制,.net提供了基于代码的安全机制,由于中间语言提供了类型安全性,CLR在运行前检查代码,确定是否有需要的安全权限, CLR没有权限则不能执行该代码。

 

5. 更好的程序组件结构(应用程序域和程序集):

应用程序域是指进程空间中的内存区域作为一个应用程序域,用于组件及应用程序之间的安全快速的通信

程序集

应用程序域(进程空间中):原来window应用程序组件DLL是通过加载在同一进程中(4GB的内存空间及安全标识,一个组件出错会影响到其它组件,导致崩溃),或者exe间是通过进程间复制数据实现通信的(内存共享机制,也会带来性能上的损失)。

.net CLR引入了应用程序域,希望可以解决这样的问题。一个进程空间内可以有多个应用程序域,一个应用程序域大致对应一个应用程序,执行的线程都对应一个具体的应用程序域。

这样理论上将需要通信的应用程序加入到相同进程中的一个应用程序域中,那么进程空间中的应用程序就可以直接的访问彼此的数据,但是有中间语言的类型安全机制(C#不建议使用指针,CLR会对数组边界进行安全检查保证不越界),所以除非明确使用不安全的特性,否则不能进行通信。但可以通过.net远程服务来快速的在安全或不安全特性的应用程序间相互通信或共享数据。

而对于不同组件间通信,可以将组件划分到不同的应用程序域中,一个大的应用程序就由多个应用程序域组成。这样组件之间既可以快速的通信且不会导致一个组件出错,会影响整个系统的崩溃。

程序集(磁盘组件中):原来是.lib,.dll库组件,exe运行程序的程序体系结构,.net中使用了程序集概念。程序集是为了解决以前COM组件注册麻烦COM组件信息获取麻烦(需要从注册表中获取组件的GUID和接口, 属性和方法也需要从类库中获取), 可能组件数据信息不同步问题(共享数据被塞满,dll被其它同名dll覆盖)。

程序集(assembly)是包含编译好的,面向.net CLR的代码逻辑单元,描述了程序集中所有类型,和这些类型的成员细节。

文件集的方式解决注册麻烦(直接存放),用程序集清单和元数据解决组件信息获取麻烦问题,及加载程序集时候用程序集入口文件描述了其它文件的细节、散列、内容,避免文件被替换或塞满,依然加载程序集,导致数据分散后不同步的问题。

     一个程序集可以存储在多个文件中(动态程序集存储在内存中),如果一个程序集存储在多个文件中,其中有一个包含入口点的主文件,该文件描述了程序集中的其它文件细节、散列和内容,如果一个文件被替换或被塞满,系统肯定会检测出来,并拒绝加载程序集。

程序集分为:可执行程序集和库程序集,它们使用相同的程序集结构,只是可执行的程序集包含了一个主程序入口点。也可以程序是否运行分为静态程序集,动态程序集,静态程序集存储在磁盘文件中,动态程序集存储在内存中。类型分为:共享程序集和私有程序集

  私有程序集:只有单一的应用程序可以使用,.net程序集默认是私有程序集,安装非常简单,只需要把相应的文件放在文件系统中对应的文件夹中即可(不需要注册表项)。私有程序集不能被其它程序使用,因为应用程序只能加载位于主执行文件所在文件夹或其子文件夹中的程序集。

 共享程序集:其它的应用程序也可以使用的公共库,需要能够实现快速共享,需要防止程序集命名冲突,程序集不同版本的相互覆盖。

共享:共享程序集需要特殊的处理,需要用.net工具来完成,将共享程序集放置在全局程序集高速缓存(GAC)中建立一个小的文件夹层次结构并对共享程序集进行检查。

命名冲突:共享程序集应根据私有密钥加密法指定一个名称(私有程序集只需要指定一个和主文件名相同的名字即可),它必须由引用共享程序集的程序来引用。

版本覆盖:可以在程序集清单中指定版本信息来解决,也可以通过同时安装来解决。


其它:

特性:在程序中提供某些项相关的信息,供编译器使用。.net提供了机制。在文件说明书中十分有用,可和反射技术一起使用,根据特性执行编程任务。使得一种语言中定义,另一种语言中可以读取。

反射:利用程序集描述的类型和类型成员详细信息,可在运行期获取特性的详细信息,或者作为实例化类、调用方法的一种间接的方式,如果把方法上的类名指定为字符串(类名为参数),就可以选择类来实例化方法,以便在运行时调用,而不是编译时调用。

64bit支持,泛型和迭代器,匿名方法,部分类,可空类型。


三、缺点:

1. 底层和高性能不合适:不合适做时间性能很高(高速算法)或空间性能很灵活(内存立即释放)的程序,因为中间语言和编译过程,比C/C++Native类型的语言会慢一些,内存自动回收难以立即释放不需要的内存,不采用内联函数和析构函数(不建议)。

2.Windows平台以外支持有限: mono不够成熟好用,window以外Java,Python等是很强大和同样优秀的。


四、总结:

C#更像是一门胶水和强大应用层语言(底层都是C/C++, WINAPI, COM 的OLE VB, DirectX, 或者mono项目上定制的库);.net基于ILCLR运行时库,和应用程序集,应用程序域却是一个对应用程序编译和应用程序组成体系比较大的创新; 但优点同时也会带来缺点,底层或实时高性能应用程序方面难以代替C/C++,windows平台以外的应用开发还需要不断的进步(Xamarin, Unity做得还不错), 故也不能替代java,oc,python,lua等众前辈或后生。总之语言都是一种武器而已。

.net在除了语言机制方面的特色,还有应用程序体系上面的创新,用了程序集管理公用和私有程序集,实现同一个程序多个版本共存安装和卸载更加方便,可以从程序集很快获得应用程序信息。用了应用程序域管理进程空间中的程序内部和外部的各个组件通信更加方便。


net框架最强的是在IL CTS编译为中间语言实现了多种遵守CTS类型的语言在语言级别的相互通信而不是COM的二进制级别,.net 的CLR在运行时候管理应用程序,包括底层访问如COM,内存自动回收,安全级别控制和应用程序域的划分和通信,和解释型语言的通信


.net在除了语言机制方面的特色,还有应用程序体系上面的创新,用了程序集管理公用和私有程序集,实现同一个程序多个版本共存安装和卸载更加方便,可以从程序集很快获得应用程序信息。用了应用程序域管理进程空间中的程序内部和外部的各个组件通信更加方便。

C#支持面向对象,范型模板,容器数据结构和算法迭代器,函数指针的委托,事件,属性,正则表达式,函数形式编程,异步机制,反射特性,但都是简单的多用即可。

优点明显缺点也同样存在,相比跨平台主要是性能方面的损失,高性能程序还是用C/C++编写,因为C#没有高性能程序的特性主要是指针操控内存,和内存的手动申请内存池特性和及时释放,没有面向对象中的内联函数和析构函数及时调用,从程序编译方面是需要才编译不会像CC++全部提前编译好,不过现在硬件越来越快,即时编译型JIT(c#和java,以及其它大多数)和解释型语言能够应付绝大多数的应用,关键效率还是在程序员自己的设计算法和内存管理。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值