前言

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. Linux使用手册

    一.开关机 sync :把内存中的数据写到磁盘中(关机.重启前都需先执行sync) shutdown -rnow或reboot :立刻重启 shutdown -hnow :立刻关机 shutdown ...

  2. 获取ul下面最后一个li或ul中有多少个li

    获取ul下面最后一个li或ul中有多少个li 先获取ul的对象,再通过这个对象获取li的list用for循环取值text之类的 def set_city(self, base_info): quali ...

  3. git 本机链接多库配置

    git config --list 查看所有配置 // 提交时读取用户名称及邮箱优先级 --local > --global > --system // 全局配置用户名称及邮箱 git c ...

  4. 旷世提出类别正则化的域自适应目标检测模型,缓解场景多样的痛点 | CVPR 2020

    论文基于DA Faster R-CNN系列提出类别正则化框架,充分利用多标签分类的弱定位能力以及图片级预测和实例级预测的类一致性,从实验结果来看,类该方法能够很好地提升DA Faster R-CNN系 ...

  5. Perl入门(三)Perl的数组

    Perl数组的声明方式 Perl使用"@"符号声明一个数组:@array: 使用"()"或"qw()"声明数组中元素: 一个完整的声明方式为 ...

  6. Spring-AOP:一、注解demo及基本概念

    切面:Aspect 切面=切入点+通知.在老的spring版本中通常用xml配置,现在通常是一个类带上@Aspect注解.切面负责将 横切逻辑(通知) 编织 到指定的连接点中. 目标对象:Target ...

  7. activiti学习笔记一

    activiti学习笔记 在讲activiti之前我们必须先了解一下什么是工作流,什么是工作流引擎. 在我们的日常工作中,我们会碰到很多流程化的东西,什么是流程化呢,其实通俗来讲就是有一系列固定的步骤 ...

  8. C# 模型赋值

    /// <summary> /// 模型赋值 /// </summary> /// <param name="target">目标</pa ...

  9. [CEOI1999]Parity Game 题解

    P5937 [CEOI1999]Parity Game 洛谷P5937 P5937 [CEOI1999]Parity Game 前言: 个人感觉这道题初看想不到并查集啊!(说实话我题都没读懂,第二遍才 ...

  10. 部署LNMP环境——Yum安装(113资讯网)

    Yum安装优点:安装东西,方便快捷,特别是不用考虑包依赖 教程(Centos做演示,其他系统大同小异): 1.更换国内Yum源: [root@root xx ]# rm -rf /etc/yum.re ...