前言

c# 是怎么运行的呢?是否和java一样运行在像jvm的虚拟机上呢?其实差不多,但是更广泛。

c# 运行环境不仅c#可以运行,符合.net framework 开发规范的都可以运行。

c# 程序在.net framework 上运行,而这个.net framework是windows独有的,所以这就是为什么以前c#不跨域的原因,现在c#可以运行在.net core 上,而.net core 跨平台还跨语言。

无论.net core还是.net framework都包括名为(公共语言运行时(CLR))的虚执行系统和一组统一的类库。

正文

什么是CLR

下面是对CLR的介绍:

CLR 是由 Microsoft 执行的公共语言基础结构 (CLI) 的商业实现,CLI 是作为执行和开发环境(语言和库在其中无缝协作)创建依据的国际标准。

这样解释似乎不够通俗,那么它到底干了啥呢。

举几个例子:

(1)类加载器:管理元数据,加载和在内存中布局类;
(2)Micorsoft 中间语言(MSIL)到本地代码编译器:通过即时编译把Micorsoft 中间语言转换为本地代码;
(3)代码管理器:管理和执行代码;
(4)垃圾回收器:为NET.Framework下的所有对象提供自动生命期管理,支持多处理器,可扩展;
(5)安全引擎:提供基于证据的安全,基于用户身份和代码来源;
(6)调试器:使开发者能够调试应用程序和根据代码执行;
(7)类型检查器:不允许不安全的类型转换和未初始化变量MSIL可被校验以保证类型安全。

这样一看这和java 的虚拟机非常像啊,这东西难道就是虚拟机。

下面这种图,一看就更像了啊:

不管是什么语言,在.net 平台上开发,然后转换成MSIL语言(这里解释一下为什么CLR为什么叫公共语言运行时,因为只要能编译成MSIL就能在这上面运行),然后通过CLR运行在windows上。

那么CLR 是否是像JVM一样的虚拟机呢?

CLR是一个支持多种编程语言及多语言互操作,完整的高级虚拟机。他们做的事情差不多,但是他们的实现原理和运行方式差异巨大。

具体可参考:https://github.com/dotnet/coreclr/blob/master/Documentation/botr/intro-to-clr.md

既然CLR是一个运行公共语言的虚拟机,运行的还是MSIL语言,那么这个MSIL语言是怎么来的呢?这就是微软贡献特别大的地方了,微软向ECMA提供了一份公共语言开发的规范。

下面贴一下概念:

·CLR(公共语言运行库)是一个CLI的实现,包含了.NET运行引擎和符合CLI的类库。我们开发的几乎所有的.NET程序都基于CLR的类库来实现,并且运行在CLR提供的运行引擎之上。

·CLI(公共语言基础)是微软公司向ECMA提交的一份语言和数据格式规范,CLR是目前为止唯一一个公共语言基础的实现版本。CLI包括了公共类型系统(CTS)、公共中间语言(CIL)、底部文件格式以及元数据格式等

·CTS(公共类型系统)定义了一个能够在CLR上运行的语言规范。尽管有很多语言本身不符合CTS规范,但是通过加强编译器,改变语言附加规范等手段,使得许多语言能够编写出能在CLR上运行的程序。
一种语言编写的程序编译能够在CLR上运行,并不代表这种语言本身完全符合CTS的规范。例如C++语言,仍然保持了其不符合CTS规范的部分,并且在编译时把这部分不符合CTS的代码编译成原始代码而非中间代码。 ·CLS(公共语言规范)是CTS的一个子集,它定义了希望编写在.NET平台上运行的程序的语言所需符合的最小规范。正因为.NET允许由不同语言编写的程序一起执行,所以才制定出CLS规范,
用以避免不同语言特性产生的错误。在.NET Framework中,几乎所有(但不是所有)的类都是与CLS兼容的。在MSDN文档说明中,不兼容的类和方法都被特别标记为不兼容,例如System命名空间中的UInt32结构。
UInt32表示32位无符号整数。并不是所有的语言(例如Visual Basic.NET或J#)都支持无符号的数据类型,这种数据类型是与CLS不兼容的。

既然是介绍c#,那么就看下c# 到CLR的运行过程吧。如下图:

由上图可以看到只需要修改下面部分,即可实现将原来windows的那一套搬运到不同的平台上。

现在的.net core就是通过修改这部分来实现跨平台的,真的是大手笔。以前有一个mono(Mono根据C#和CLR的ECMA标准实现了一份Linux下的CLR,比如说,Linux里没有注册表的概念,Mono用一个.ini文件来模拟注册表。),

我尝试使用过,小型网站用用还是可以的(老项目没有windows主机可以放一下),效率的确低了一些,只是尝试部署过一次。

.NET Standard

这东西比较关键,是一套规范。

官方文档这样介绍道:

NET Standard 是一套正式的 .NET API 规范,有望在所有 .NET 实现中推出。
推出 .NET Standard 的背后动机是要提高 .NET 生态系统中的一致性。
ECMA 335 继续为 .NET 实现行为建立统一性,尽管 ECMA 335 指定了一小组标准库,但 .NET Standard 规范包含范围更广的 .NET API。

这东西伴随着.net core 一起诞生。

这东西出现是解决这样一个问题的。

现在有.net framewore还有.net core,那么就有一个问题啊,都是用c#在不同平台上开发,他们调用的api是否一致呢?

比如说有个在.net framework 上有个叫做System.IO.FileSystem的api库,那么在.net core上文件操作是否也叫这个呢?

所以为了统一就制定了一套规范,叫做标准库,是.net framework和.net core 都有的,有些是.net core上没有的,比如D3D只有windows操作系统上有,Linux根本就没有这个东西,所以不会加入标准库。

同理用标准库开发的东西是可以在两套平台上跑的。

NET Standard 一直在更新,这是历史原因,那就是当时出来.net core的时候有些api是.net framework 有但是.net core没有的,这个也不是说是windows都有的api,而是说当时来不及。

NET Standard 2.0 中的新增功能这样写道:

.NET Standard 2.0 新增了以下功能:

大幅扩展了 API 集

.NET Standard 版本 1.6 中包含了相对较小的一部分 API。 

不包含的 API 许多都是 .NET Framework 或 Xamarin 中的常用 API。

这样一来,开发变得更为棘手,因为开发人员必须在开发定目标到多个 .NET 实现的应用和库时,寻找常用 API 的合适替代项。

为了消除此限制,.NET Standard 2.0 向 Standard 旧版本 .NET Standard 1.6 中的可用 API 补充了 20,000 多个 API。

随着时间的推移,.net core现在开发就比较轻松了。

重学c#系列——c#运行原理(二)的更多相关文章

  1. 重学c#系列——datetime 和 datetimeoffset[二十一]

    前言 简单介绍一下datetime和 datetimeoffset. 正文 了解一个国家的文化,就要了解一个国家的历史. 要了解datetimeoffset,那么很有必要了解一下datetime. 表 ...

  2. 重学c#系列——字典(十一)

    前言 重学c#系列继续更新,简单看一下字典的源码. 看源码主要是解释一下江湖中的两个传言: 字典foreach 顺序是字典添加的顺序 字典删除元素后,字典顺序将会改变 正文 那么就从实例化开始看起,这 ...

  3. 重学c#系列——对c#粗浅的认识(一)

    前言 什么是c#呢? 首先你是如何读c#的呢?c sharp?或者c 井? 官方读法是:see sharp. 有没有发现开发多年,然后感觉名字不对. tip:为个人重新整理,如学习还是看官网,c# 文 ...

  4. 【转载】Spark系列之运行原理和架构

    参考 http://www.cnblogs.com/shishanyuan/p/4721326.html 1. Spark运行架构 1.1 术语定义 lApplication:Spark Applic ...

  5. 重学c#系列——list(十二)

    前言 简单介绍一下list. 正文 这里以list为介绍. private static readonly T[] s_emptyArray = new T[0]; public List() { t ...

  6. 重学c#系列——string.empty 和 "" 还有null[二十]

    前言 简单整理一下string.empty 和 "" 还有 null的区别. 正文 首先null 和 string.empty 还有 "" 是不一样的. nul ...

  7. 重学Golang系列(一): 深入理解 interface和reflect

    前言 interface(即接口),是Go语言中一个重要的概念和知识点,而功能强大的reflect正是基于interface.本文即是对Go语言中的interface和reflect基础概念和用法的一 ...

  8. 重学c#系列——c# 托管和非托管资源(三)

    前言 c# 托管和非托管比较重要,因为这涉及到资源的释放. 现在只要在计算机上运行的,无论玩出什么花来,整个什么概念,逃不过输入数据修改数据输出数据(计算机本质),这里面有个数据的输入,那么我们的内存 ...

  9. 重学c#系列——异常(六)

    前言 用户觉得异常是不好的,认为出现异常是写的人的问题. 这是不全面,错误的出现并不总是编写程序的人的原因,有时会因为应用程序的最终用户引发的动作或运行代码的环境而发生错误,比如你用android4去 ...

随机推荐

  1. C#数据结构与算法系列(三):队列

    1.介绍 队列是一个有序列表,可以用数组或是链表来实现. 遵循先入先出的原则,即:先存入队列的数据,要先取出.后存入的要后取出 队列是属于线性结构中的一种 2.图示  3.通过数组实现 public ...

  2. 解决adb检测不到夜神模拟器

    1.安装夜神模拟器 2.安装adb(安装教程——我的网盘(无邪appium环境安装.word)) 3.在D:\android-sdk_r24.4.1-windows\android-sdk-windo ...

  3. 一文带你了解Redis持久化完整版本

    本文讲解知识点 持久化的简介 RDB AOF RDB与AOF的区别 持久化应用场景 对于持久化这个功能点,其实很简单没有那么复杂 演示环境 centos7.0 redis4.0 redis存放目录:/ ...

  4. new jup在新一代中存在

    1.灰度发布服务动态路由 动态配置路由规则,实现对调用流量的精确控制.可配置基于版本.IP.自定义标签等复杂的规则.2.服务鉴权示例2需求:服务 provider-demo 只允许来自 consume ...

  5. 内存节省机制C演示

    编写代码实质是通过指令对计算机内存进行操作,计算机的硬件设备往往十分有限,尤其是内存.如何使有限的存储空间利用效率达到最大,成为了代码优化首先要考虑的事情. 比如,输入三个数比较大小并输出最小值.下面 ...

  6. Python 简明教程 --- 17,Python 模块与包

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 正确的判断来源于经验,然而经验来源于错误的判断. -- Fred Brooks 目录 我们已经知道函 ...

  7. caffe的python接口学习(1)生成配置文件

    ---恢复内容开始--- 看了denny的博客,写下自己觉得简短有用的部分 想用caffe训练数据首先要学会编写配置文件: (即便是用别人训练好的模型也要进行微调的,所以此关不可跨越) 代码就不粘贴了 ...

  8. MBA都需要学习哪些课程

    MBA课程内容详解: 1.核心课程: 管理经济学.营销管理.战略管理.组织行为学.会计学.公司财务管理.人力资源管理与开发.管理与沟通.经济法.国际贸易 2.学位课程: 商务英语(一.二).管理伦理学 ...

  9. 小白写了一堆if-else,大神实在看不下去了,竟然用策略模式直接摆平了

    这里涉及到一个关键词:策略模式,那么到底什么是策略模式呢?本文就来好好给大家讲讲策略模式,大家可以带着如下几个问题来阅读本文:   1. 如何通过策略模式优化业务逻辑代码(可以根据自己从事的工作思考) ...

  10. JavaScript学习笔记(1)

    概念: 运行在浏览器端的脚本语言. 构成: ECMAScript(语法) + DOM(文档对象模型) + BOM(浏览器对象模型) 语法: 1.区分大小写 2.变量是弱类型 数据类型: string ...