重学c#系列——c#运行原理(二)

时间:2022-09-07 17:42:03

前言

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 的虚拟机非常像啊,这东西难道就是虚拟机。

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

重学c#系列——c#运行原理(二)

不管是什么语言,在.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的运行过程吧。如下图:

重学c#系列——c#运行原理(二)

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

重学c#系列——c#运行原理(二)

现在的.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 一起诞生。

重学c#系列——c#运行原理(二)

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

现在有.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. LeetCode Binary Tree Vertical Order Traversal

    原题链接在这里:https://leetcode.com/problems/binary-tree-vertical-order-traversal/ 题目: Given a binary tree, ...

  2. 【hibernate merge】session1.merge(T entity)方法的含义和update方法的区别

    注意:  MERGE语句是SQL语句的一种.在SQL Server.Oracle数据库中可用,MySQL.PostgreSQL中不可用. 1>session1.merge(T entity) 合 ...

  3. (spring-第6回【IoC基础篇】)BeanDefinition——实例化Bean之前的第一大利器。

    上节讲了Bean实例化的内部机制,这里再复述一遍: ResourceLoader从系统中加载XML配置信息,并由Resource来表示. BeanDefinitionReader从Resource中读 ...

  4. boa服务器问题日志

    1. 某一次在登录boa服务器的时候,不知哪里的问题,无法登录「192.168.1.0-192.168.3.255」网段的设备,但是公司IP网段的机器都可以用.最终发现,问题出现在自己的PC添加了浏览 ...

  5. [C入门 - 游戏编程系列] 贪吃蛇篇(六) - 蛇实现

    这一篇是关于设置蛇的属性的,接上一篇(五). 设置蛇的速度,很简单,只要不是负数就行了. void SNK_SetSnakeSpeed(Snake *snake, int speed) { ) sna ...

  6. ASP.NET Core MVC I/O编程模型

    1. ASP.NET Core MVC I/O编程模型 1.1. I/O编程模型浅析 1.2. 同步阻塞I/O 1.3. 同步非阻塞I/O 1.4. 异步I/O 1.5. 总结 1.1. I/O编程模 ...

  7. 使用Python定制词云

    一.实验介绍 1.1 实验内容 在互联网时代,人们获取信息的途径多种多样,大量的信息涌入到人们的视线中.如何从浩如烟海的信息中提炼出关键信息,滤除垃圾信息,一直是现代人关注的问题.在这个信息爆炸的时代 ...

  8. Java~时间戳小知识

    大叔对java时间戳使用的总结 Java里的Date对象有方法setTime,主要是将一个时间戳转成一个日期对象,而这个时间戳的标准是unix标准,即当前时间与1970/1/1相差的毫秒数,记得是毫秒 ...

  9. wav文件格式分析与详解

    WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows 3.1操作系统上,文件扩展名为WAV,是WaveFom的简写,也称为波形文件,可直接存储声音波形, ...

  10. Phpstorm配置scss不生成缓存

    --no-cache 加上这个,就不会生成 .sass-cache 文件夹了.