CodeSnippet.Cn
代码片段
Csharp
架构设计
.NetCore
西班牙语
kubernetes
MySql
Redis
Algorithm
Ubuntu
Linux
Other
.NetMvc
VisualStudio
Git
pm
Python
WPF
java
Plug-In
分布式
CSS
微服务架构
JavaScript
DataStructure
Shared
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(三)
0
.NetCore
Csharp
小笨蛋
发布于:2021年03月15日
更新于:2021年03月15日
123
#custom-toc-container
**[通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(一)](https://www.codesnippet.cn/home/list/16 "通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(一)")** **[通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(二)](https://www.codesnippet.cn/home/list/17 "通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(二)")** ### 计算机是如何运行程序的? 接下来我要说什么是.NET的跨平台,并解释为什么能够跨语言。不过要想知道什么是跨平台,首先你得知道一个程序是如何在本机上运行的。 #### 什么是CPU CPU,全称Central Processing Unit,叫做中央处理器,它是一块超大规模的集成电路,是计算机组成上必不可少的组成硬件,没了它,计算机就是个壳。 无论你编程水平怎样,你都应该先知道,CPU是一台计算机的运算核心和控制核心,CPU从存储器或高速缓冲存储器中取出指令,放入指令寄存器,并对指令译码,执行指令。 我们运行一个程序,CPU就会不断的读取程序中的指令并执行,直到关闭程序。事实上,从电脑开机开始,CPU就一直在不断的执行指令直到电脑关机。 #### 什么是高级编程语言 在计算机角度,每一种CPU类型都有自己可以识别的一套指令集,计算机不管你这个程序是用什么语言来编写的,其最终只认其CPU能够识别的二进制指令集。 在早期计算机刚发展的时代,人们都是直接输入01010101这样的没有语义的二进制指令来让计算机工作的,可读性几乎没有,没人愿意直接编写那些没有可读性、繁琐、费时,易出差错的二进制01代码,所以后来才出现了编程语言。 编程语言的诞生,使得人们编写的代码有了可读性,有了语义,与直接用01相比,更有利于记忆。 而前面说了,计算机最终只识别二进制的指令,那么,我们用编程语言编写出来的代码就必须要转换成供机器识别的指令。 就像这样: ```c code: 1+2 function 翻译方法(参数:code) { ... "1"=>"001"; "2"=>"002"; "+"=>"000"; return 能让机器识别的二进制代码; } call 翻译方法("1+2") => "001 000 002" ``` 所以从一门编程语言所编写的代码文件转换成能让本机识别的指令,这中间是需要一个翻译的过程。 而我们现在计算机上是运载着操作系统的,光翻译成机器指令也不行,还得让代码文件转化成可供操作系统执行的程序才行。 那么这些步骤,就是编程语言所对应的编译环节的工程了。这个翻译过程是需要工具来完成,我们把它叫做 编译器。 不同厂商的CPU有着不同的指令集,为了克服面向CPU的指令集的难读、难编、难记和易出错的缺点,后来就出现了面向特定CPU的特定汇编语言, 比如我打上这样的x86汇编指令 mov ax,bx ,然后用上用机器码做的汇编器,它将会被翻译成 1000100111011000 这样的二进制01格式的机器指令. 不同CPU架构上的汇编语言指令不同,而为了统一一套写法,同时又不失汇编的表达能力,C语言就诞生了。 用C语言写的代码文件,会被C编译器先转换成对应平台的汇编指令,再转成机器码,最后将这些过程中产生的中间模块链接成一个可以被操作系统执行的程序。 那么汇编语言和C语言比较,我们就不需要去阅读特定CPU的汇编码,我只需要写通用的C源码就可以实现程序的编写,我们用将更偏机器实现的汇编语言称为低级语言,与汇编相比,C语言就称之为高级语言。 在看看我们C#,我们在编码的时候都不需要过于偏向特定平台的实现,翻译过程也基本遵循这个过程。它的编译模型和C语言类似,都是属于这种间接转换的中间步骤,故而能够跨平台。 所以就类似于C/C#等这样的高级语言来说是不区分平台的,而在于其背后支持的这个 翻译原理 是否能支持其它平台。 ### 什么是托管代码,托管语言,托管模块? 作为一门年轻的语言,C#借鉴了许多语言的长处,与C比较,C#则更为高级。 往往一段简小的C#代码,其功能却相当于C的一大段代码,并且用C#语言你几乎不需要指针的使用,这也就意味着你几乎不需要进行人为的内存管控与安全考虑因素,也不需要多懂一些操作系统的知识,这让编写程序变得更加轻松和快捷。 如果说C#一段代码可以完成其它低级语言一大段任务,那么我们可以说它特性丰富或者类库丰富。而用C#编程不需要人为内存管控是怎么做到的呢? .NET提供了一个垃圾回收器(GC)来完成这部分工作,当你创建类型的时候,它会自动给你分配所需要的这部分内存空间。就相当于,有一个专门的软件或进程,它会读取你的代码,然后当你执行这行代码的时候,它帮你做了内存分配工作。 这部分本该你做的工作,它帮你做了,这就是“托管”的概念。比如现实中 托管店铺、托管教育等这样的别人替你完成的概念。 因此,C#被称之为托管语言。C#编写的代码也就称之为托管代码,C#生成的模块称之为托管模块等。(对于托管的资源,是不需要也无法我们人工去干预的,但我们可以了解它的一些机制原理,在后文我会简单介绍。) 只要有比较,就会产生概念。那么在C#角度,那些脱离了.NET提供的诸如垃圾回收器这样的环境管制,就是对应的 非托管了。 #### 非托管的异常 我们编写的程序有的模块是由托管代码编写,有的模块则调用了非托管代码。在.NET Framework中也有一套基于此操作系统SEH的异常机制,理想的机制设定下我们可以直接通过catch(e)或catch来捕获指定的异常和框架设计人员允许我们捕获的异常。 而异常类型的级别也有大有小,有小到可以直接框架本身或用代码处理的,有大到需要操作系统的异常机制来处理。.NET会对那些能让程序崩溃的异常类型给进行标记,对于这部分异常,在.NET Framework 4.0之前允许开发人员在代码中自己去处理,但4.0版本之后有所变更,这些被标记的异常默认不会在托管环境中抛出(即无法catch到),而是由操作系统的SEH机制去处理。 不过如果你仍然想在代码中捕获处理这样的异常也是可以的,你可以对需要捕获的方法上标记[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute]特性,就可以在该方法内通过catch捕获到该类型的异常。你也可以通过在配置文件中添加运行时节点来对全局进行这样的一个配置: ```xml
``` HandleProcessCorruptedStateExceptions特性:https://msdn.microsoft.com/zh-cn/library/azure/system.runtime.exceptionservices.handleprocesscorruptedstateexceptionsattribute.aspx SEHException类:https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.sehexception(v=vs.100).aspx 处理损坏状态异常博客专栏: https://msdn.microsoft.com/zh-cn/magazine/dd419661.aspx ### 什么是CLR,.NET虚拟机? 实际上,.NET不仅提供了自动内存管理的支持,他还提供了一些列的如类型安全、应用程序域、异常机制等支持,这些 都被统称为CLR公共语言运行库。 CLR是.NET类型系统的基础,所有的.NET技术都是建立在此之上,熟悉它可以帮助我们更好的理解框架组件的核心、原理。 在我们执行托管代码之前,总会先运行这些运行库代码,通过运行库的代码调用,从而构成了一个用来支持托管程序的运行环境,进而完成诸如不需要开发人员手动管理内存,一套代码即可在各大平台跑的这样的操作。 这套环境及体系之完善,以至于就像一个小型的系统一样,所以通常形象的称CLR为".NET虚拟机"。那么,如果以进程为最低端,进程的上面就是.NET虚拟机(CLR),而虚拟机的上面才是我们的托管代码。换句话说,托管程序实际上是寄宿于.NET虚拟机中。 ### 什么是CLR宿主进程,运行时主机 那么相对应的,容纳.NET虚拟机的进程就是CLR宿主进程了,该程序称之为运行时主机。 这些运行库的代码,全是由C/C++编写,具体表现为以mscoree.dll为代表的核心dll文件,该dll提供了N多函数用来构建一个CLR环境 ,最后当运行时环境构建完毕(一些函数执行完毕)后,调用_CorDllMain或_CorExeMain来查找并执行托管程序的入口方法(如控制台就是Main方法)。 如果你足够熟悉CLR,那么你完全可以在一个非托管程序中通过调用运行库函数来定制CLR并执行托管代码。 像SqlServer就集成了CLR,可以使用任何 .NET Framework 语言编写存储过程、触发器、用户定义类型、用户定义函数(标量函数和表值函数)以及用户定义的聚合函数。 有关CLR大纲介绍: https://msdn.microsoft.com/zh-cn/library/9x0wh2z3(v=vs.85).aspx CLR集成: https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/ms131052(v%3dsql.100) 构造CLR的接口:https://msdn.microsoft.com/zh-cn/library/ms231039(v=vs.85).aspx 适用于 .NET Framework 2.0 的宿主接口:https://msdn.microsoft.com/zh-cn/library/ms164336(v=vs.85).aspx 选择CLR版本: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element 所以C#编写的程序如果想运行就必须要依靠.NET提供的CLR环境来支持。 而CLR是.NET技术框架中的一部分,故只要在Windows系统中安装.NET Framework即可。 ### Windows系统自带.NET Framework Windows系统默认安装的有.NET Framework,并且可以安装多个.NET Framework版本,你也不需要因此卸载,因为你使用的应用程序可能依赖于特定版本,如果你移除该版本,则应用程序可能会中断。 Microsoft .NET Framework百度百科下有windows系统默认安装的.NET版本 ![图片alt](/uploads/images/20210605/145743-e0d1b75d4798401089f2c0ab5e199cb7.png ''图片title'') ### .NET Framework 4.0.30319 在%SystemRoot%\Microsoft.NET下的Framework和Framework64文件夹中分别可以看到32位和64位的.NET Framework安装的版本。 我们点进去可以看到以.NET版本号为命名的文件夹,有2.0,3.0,3.5,4.0这几个文件夹。 ![图片alt](/uploads/images/20210605/145805-a42c5e67bcc64f41b10ada76330ec105.png ''图片title'') #### .NET Framework4.X覆盖更新 要知道.NET Framework版本目前已经迭代到4.7系列,电脑上明明安装了比4.0更高版本的.NET Framework,然而从文件夹上来看,最高不过4.0,这是为何? 原来自.NET Framework 4以来的所有.NET Framework版本都是直接在v4.0.30319文件夹上覆盖更新,并且无法安装以前的4.x系列的老版本,所以v4.0.30319这个目录中其实放的是你最后一次更新的NET Framework版本。 .NET Framework覆盖更新:https://docs.microsoft.com/en-us/dotnet/framework/install/guide-for-developers #### 如何确认本机安装了哪些.NET Framework和对应CLR的版本? 我们可以通过注册表等其它方式来查看安装的最新版本:https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed 。 不过如果不想那么复杂的话,还有种最直接简单的: 那就是进入该目录文件夹,随便找到几个文件对其右键,然后点击详细信息即可查看到对应的文件版本,可以依据文件版本估摸出.NET Framework版本,比如csc.exe文件。 ![图片alt](/uploads/images/20210605/145836-e1b23f57e0ef47ce95428ea0c26e3fa8.png ''图片title'')
这里⇓感觉得写点什么,要不显得有点空,但还没想好写什么...
返回顶部
About
京ICP备13038605号
© 代码片段 2024