C#与.net的一个关系
.NET是一门体系结构。C#是不能独立于.NET之外的,它必须要和.NET Framewoke一起考虑。也就是说C#的编译器其实是专门为.NET准备的,所以C#编写的代码总是使用.NET Framewoke。C#本身只是一门语言,尽管它是用于生成面向.NET环境的代码,但是它本身不是.NET的一部分。.NET支持的一些特性它不一定就支持,反过来C#支持的一些特性(例如运算符重载).NET他就不支持。所以他们并不是包含的关系。以下是一些关系结论:
①、我们通过C#的体系结构和方法论反映了.NET的体系结构;
②、在许多情况下C#的语言功能取决于.NET的功能。
这样大家就不会把他们搞混了。所以呢我们除了学习C#的语法之外,也应该去了解.NET的东西。去看之前我写过的关于C#的一些基础知识,就是我们.NET体系的知识,可以回看一下。再稍微重复下一些:
CLR | |
公共语言运行库 (common language runtime,CLR) 是托管代码执行核心中的引擎。 | |
运行库为托管代码提供各种服务,如跨语言集成、代码访问安全性(即数据类型是清楚的,唯一的)、对象生存期管理、调试和分析支持。 | |
它是整个.NET框架的核心,它为.NET应用程序提供了一个托管的代码执行环境。 | |
它实际上是驻留在内存里的一段代理代码,负责应用程序在整个执行期间的代码管理工作。 | |
使用基于公共语言运行库的语言编译器开发的代码称为托管代码; | |
简而言之 CLR 负责提取托管代码、将其编译成机器代码,然后执行它。 |
C#代码编译过程 | |
C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言指令; | |
JIT编译器把IL代码转为机器识别的机器代码。如下图 |
平台无关性
讲到这里的时候,就要提到.NET Code,目前推出来的就是它有跨平台,之前的.NET只能运行在windows上。平台无关性就是我们把代码编译为中间语言,它可以放在任一平台去运行。比如java编译为java字节码就可以得到java平台无关性。我们.NET的IL比java的大,它总是即时编译的(JIT,不是一次编译整个程序,而是编译调用到的内容,可以联想操作系统的相关知识),而Java字节码常常是解释性的,它不是即时编译,它需要把java字节码转换成内部可执行代码再去转成机器码。
语言的互操作性
互操作性就是任一语言编译成中间语言代后,这些中间语言可以互相交互操作。
中间语言的主要特征:
①、面向对象和使用接口;(使用.NET编译为中间语言时,必须用面向对象的方法来编程,但是这不能提供语言的互操作性)
②、值类型和引用类型之间的显著差异;(中间语言也有数据存储的规范:引用类型的实例存在托管堆,值类型存储在堆栈中)
③、强数据类型化;(所有的变量都清晰的标明属于某个数据类型)
④、使用异常来处理错误;
⑤、使用特性(attribute)
DLR
Dynamic Language Runtime(动态语言运行时,DLR) |
DLR是添加到CLR的一系列服务,它允许添加动态语言,如Ruby和Python,并使C#具备和这些动态语言相同的某些功能. |
DLR最主要的一点就是加入了动态编程语言,还有与COM交互 |
我们在讲到DLR的时候,就要来说一说,我们C#一直都标榜是一门静态语言,但是现在的C#它是支持动态语言的。
使用动态语言有什么优点呢?
①:动态它可以直接运行而不需要先编译再运行,也就是他是读取->执行->输出结果,而不是像我们常规的C#先编译->排错->执行。
②:上面①优点这就引申出另一个优点,就是当我们要添加新的功能动作时,只需要为动态对象直接加上,就可以使用,而不需要先去编译,再把编译后的文件拿去运行。
③:静态是在编译的时候解析的,动态是在运行的时候解析的,结合CLR我们可以知道,动态的不需要我们多做类型转换的代码,所以代码量更紧凑。
使用动态语言有什么缺点呢?
既然它是运行中解析,那么排错就变得困难,不利于复杂性逻辑的开发。
扯到这里,就顺便扯出来C# 中的var与dynamic他们的区别:
①、绑定时间不一样:var是早期绑定,dynamic绑定则会在运行时进行(dynamic的出现让C#具有了弱语言类型的特性。
②、编译时赋予类型不一样:编译器就会自动匹配var变量的实际类型,而dynamic被编译后是一个Object类型。也就是说var的类型由赋初值时决定,而dynamic是一直可以变的。
③、基于原理不同:dynamic是基于DLR,第一次运行后会缓存起来。
④、静态绑定和动态绑定之间最显著的差异是扩展方法。
使用动态绑定的坏处 | |
缺点是在运行时会发生异常以及没有静态类型检查导致的安全性的缺失 | |
动态绑定也会对性能造成影响。因为DLR的缓存机制对反复调用一个动态表达式进行了优化,允许在一个循环中高效的调用。 | |
这个优化后的机制能够使一个动态表达式的处理负载降低在100ns以内。 |
使用动态绑定的好处 | |
明显的好处是不用为每个不同的值类型提供不同的实现。 例如:dynamic str=1;str = “TEST”+str;这时str=TEST1,注意必须是能转换的,不然就会运行中报错。 |
|
dynamic 可在反射、json反序列化时使用、已达到减少代码量的效果。任何实例都能隐式的与dynamic类型实例互换,因为它是object。 | |
编译器对dynamic进行了优化,比没有经过缓存的反射效率快了很多。 |