一、原理:
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服务,client请求,服务端返回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程序集默认是私有程序集,安装很easy,仅仅须要把相应的文件放在文件系统中相应的目录中就可以(不须要注冊表项)。私有程序集不能被其他程序使用,由于应用程序仅仅能载入位于主运行文件所在目录或其子目录中的程序集。
共享程序集:其他的应用程序也可以使用的公共库,须要可以实现高速共享,须要防止程序集命名冲突,程序集不同版本号的相互覆盖。
共享:共享程序集须要特殊的处理,须要用.net工具来完毕,将共享程序集放置在全局程序集快速缓存(GAC)中建立一个小的目录层次结构并对共享程序集进行检查。
命名冲突:共享程序集应依据私有密钥加密法指定一个名称(私有程序集仅仅须要指定一个和主文件名称同样的名字就可以),它必须由引用共享程序集的程序来引用。
版本号覆盖:能够在程序集清单中指定版本号信息来解决,也能够通过同一时候安装来解决。
其他:
特性:在程序中提供某些项相关的信息,供编译器使用。.net提供了机制。在文件说明书中十分实用,可和反射技术一起使用,依据特性运行编程任务。使得一种语言中定义,还有一种语言中能够读取。
反射:利用程序集描写叙述的类型和类型成员具体信息,可在执行期获取特性的具体信息,或者作为实例化类、调用方法的一种间接的方式,假设把方法上的类名指定为字符串(类名为參数),就能够选择类来实例化方法,以便在执行时调用,而不是编译时调用。
64bit支持,泛型和迭代器,匿名方法,部分类,可空类型。
三、缺点:
1. 底层和高性能不合适:不合适做时间性能非常高(快速算法)或空间性能非常灵活(内存马上释放)的程序,由于中间语言和编译过程,比C/C++Native类型的语言会慢一些,内存自己主动回收难以马上释放不须要的内存,不採用内联函数和析构函数(不建议)。
2.Windows平台以外支持有限: mono不够成熟好用,window以外Java,Python等是非常强大和相同优秀的。
四、总结:
C#更像是一门胶水和强大应用层语言(底层都是C/C++, WINAPI, COM 的OLE VB, DirectX, 或者mono项目上定制的库);且.net基于IL的CLR执行时库,和应用程序集,应用程序域却是一个相应用程序编译和应用程序组成体系比較大的创新; 但长处同一时候也会带来缺点,底层或实时高性能应用程序方面难以取代C/C++,windows平台以外的应用开发还须要不断的进步(Xamarin, Unity做得还不错), 故也不能替代java,oc,python,lua等众前辈或后生。总之语言都是一种武器而已。