什么是.NET?什么是.NETFramework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从类型系统开始讲起,我将通过跨语言操作这个例子来逐渐引入一系列.NET的相关概念,这主要包括:CLS、CTS(CLI)、FCL、Windows下CLR的相关核心组成、Windows下托管程序运行概念、什么是.NETFramework,.NETCore,.NETStandard及一些VS编译器相关杂项和相关阅读链接。完整的从上读到下则你可以理解个大概的.NET体系。
文章是我一字一字亲手码出来的,每天下班用休息时间写一点,持续了二十来天。且对于文章上下衔接、概念引入花了很多心思,致力让很多概念在本文中显得通俗。但毕竟.NET系统很庞大,本文篇幅有限,所以在部分小节中我会给出延伸阅读的链接,在文章结尾我给出了一些小的建议,希望能对需要帮助的人带来帮助,如果想与我交流可以文章留言或者加.NET技术交流群:
目录
.NET和C#是什么关系
跨语言和跨平台是什么
什么是跨语言互操作,什么是CLS
CLS异常
什么是CTS?
什么是类库?
什么是基础类库BCL?
什么是框架类库FCL?
什么是基元类型?
System.Object的意义
计算机是如何运行程序的?
什么是CPU?
什么是高级编程语言?
什么是托管代码,托管语言,托管模块?
非托管的异常
什么是CLR,.NET虚拟机?
什么是CLR宿主进程,运行时主机?
Windows系统自带.NETFramework
.NETFramework4.0.
.NETFramework4.X覆盖更新
如何确认本机安装了哪些.NETFramework和对应CLR的版本?
什么是程序集
用csc.exe进行编译
.NET程序执行原理
JIT编译
AOT编译
程序集的规则
程序集的加载方式
强名称程序集
程序集搜索规则
项目的依赖顺序
为什么Newtonsoft.Json版本不一致?
如何在编译时加载两个相同的程序集
如何同时调用两个两个相同命名空间和类型的程序集?
共享程序集GAC
延伸
应用程序域
跨边界访问
AppDomain和AppPool
内存
堆栈和堆的区别
线程堆栈
为什么值类型存储在栈上
托管堆模型
选class还是struct
GC管理器
弱引用、弱事件
GC堆回收
垃圾回收对性能的影响
性能建议
.NET程序执行图
.NET的安全性
基于角色的安全性
代码访问安全性
什么是.NET
如何在VS中调试.NETFramework源代码
什么是.NETFramework
什么是.NETCore
什么是.NETStandard
.NET官方开源项目链接
VisualStudio
sln解决方案
项目模板
csproj工程文件
项目属性杂项
IntelliTrace智能追溯
链接
建议
.NET和C#是什么关系语言,是人们进行沟通表达的主要方式。编程语言,是人与机器沟通的表达方式。不同的编程语言,其侧重点不同。有的编程语言是为了科学计算而开发的,所以其语法和功能更偏向于函数式思想。有些则是为了开发应用程序而创立的,所以其语法和功能更为均衡全面。
微软公司是全球最大的电脑软件提供商,为了占据开发者市场,进而在年推出了VisualStudio(简称VS,是微软提供给开发者的工具集).NET1.0版本的开发者平台。而为了吸引更多的开发者涌入平台,微软还在年宣布推出一个特性强大并且与.NET平台无缝集成的编程语言,即C#1.0正式版。只要是.NET支持的编程语言,开发者就可以通过.NET平台提供的工具服务和框架支持便捷的开发应用程序。
C#就是为宣传.NET而创立的,它直接集成于VisualStudio.NET中,VB也在.NET1.0发布后对其进行支持,所以这两门语言与.NET平台耦合度很高,并且.NET上的技术大多都是以C#编程语言为示例,所以经常就.NET和C#混为一谈(实质上它们是相辅相成的两个概念)。而作为一个开发者平台,它不仅仅是包含开发环境、技术框架、社区论坛、服务支持等,它还强调了平台的跨语言、跨平台编程的两个特性。
跨语言和跨平台是什么跨语言:即只要是面向.NET平台的编程语言((C#、VisualBasic、C++/CLI、Eiffel、F#、IronPython、IronRuby、PowerBuilder、VisualCOBOL以及WindowsPowerShell)),用其中一种语言编写的类型可以无缝地用在另一种语言编写的应用程序中的互操作性。跨平台:一次编译,不需要任何代码修改,应用程序就可以运行在任意有.NET框架实现的平台上,即代码不依赖于操作系统,也不依赖硬件环境。
什么是跨语言互操作,什么是CLS每门语言在最初被设计时都有其在功能和语法上的定位,让不同的人使用擅长的语言去干合适的事,这在团队协作时尤为重要。.NET平台上的跨语言是通过CLS这个概念来实现的,接下来我就以C#和VB来演示什么是.NET中的跨语言互操作性。
通俗来说,虽然c#和vb是两个不同的语言,但此处c#写的类可以在vb中当做自家写的类一样正常使用。
比如我在vb中写了一个针对String的首字母大写的扩展方法,将其编译后的dll引用至C#项目中。
在C#项目中,可以像自身代码一样正常使用来自vb这个dll的扩展方法。
现在有那么多面向对象语言,但不是所有编程语言都能这样直接互操作使用,而.NET平台支持的C#和VB之所以能这样无缝衔接,先读而后知,后文将会介绍缘由。不过虽然.NET平台提供了这样一个互操作的特性,但终究语言是不一样的,每个语言有其特色和差异处,在相互操作的时候就会难免遇到一些例外情况。
比如我在C#中定义了一个基类,类里面包含一个公开的指针类型的成员,我想在vb中继承这个类,并访问这个公开的成员。
但是vb语言因为其定位不需要指针,所以并没有C#中如int*这样的指针类型,所以在vb中访问一个该语言不支持的类型会报错的,会提示:字段的类型不受支持。
再比如,C#语言中,对类名是区分大小写的,我在C#中定义了两个类,一个叫BaseBusiness,另一个叫baseBusiness。我在vb中去继承这个BaseBusiness类。
如图,在vb中访问这个类会报错的,报:"BaseBusiness"不明确,这是因为在vb中对类名是不区分大小写的。在vb中,它认为它同时访问了两个一模一样的类,所以按照vb的规则这是不合理的。那么为了在vb调用c#的程序集中避免这些因语言的差异性而导致的错误,在编写c#代码的时候就应该提前知道vb中的这些规则,来应付式的开发。
但是,如果我想不仅仅局限于C#和VB,我还想我编写的代码在.Net平台上通用的话,那么我还必须得知道.NET平台支持的每一种语言和我编写代码所使用的语言的差异,从而在编写代码中避免这些。
这几年编程语言层出不穷,在将来.NET可能还会支持更多的语言,如果说对一个开发者而言掌握所有语言的差异处这是不现实的,所以.NET专门为此参考每种语言并找出了语言间的共性,然后定义了一组规则,开发者都遵守这个规则来编码,那么代码就能被任意.NET平台支持的语言所通用。而与其说是规则,不如说它是一组语言互操作的标准规范,它就是公共语言规范-CommonLanguageSpecification,简称CLS
CLS从类型、命名、事件、属性、数组等方面对语言进行了共性的定义及规范。这些东西被提交给欧洲计算机制造联合会ECMA,称为:共同语言基础设施。
就以类型而言,CLS定义了在C#语言中符合规范的类型和不符合的有:
当然,就编码角度而言,我们不是必须要看那些详略的文档。为了方便开发者开发,.NET提供了一个特性,名叫:CLSCompliantAttribute,代码被CLSCompliantAttribute标记后,如果你写的代码不符合CLS规范的话,编译器就会给你一条警告。
值得一提的是,CLS规则只是面向那些公开可被其它程序集访问的成员,如public、继承的protected,对于该程序集的内部成员如Private、internal则不会执行该检测规则。也就是说,所适应的CLS遵从性规则,仅是那些公开的成员,而非私有实现。
那么有没有那种特殊情况,比如我通过反射技术来访问该程序集中,当前语言并不拥有的类型时会发生什么情况呢?
答案是可以尝试的,如用vb反射访问c#中的char*指针类型,即使vb中没有char*这种等价的指针类型,但mscorlib提供了针对指针类型的Pointer包装类供其访问,可以从运行时类携带的类型名称看到其原本的类型名。
可以看到,该类中的元素是不符合CLS规范的。
CLS异常提到特殊情况,还要说的一点就是异常处理。.NET框架组成中定义了异常类型系统,在编译器角度,所有catch捕获的异常都必须继承自System.Exception,如果你要调用一个由不遵循此规范的语言抛出其它类型的异常对象(C++允许抛出任何类型的异常,如C#调用C++代码,C++抛出一个string类型的异常),在C#2.0之前Catch(Exception)是捕捉不了的,但之后的版本可以。在后续版本中,微软提供了System.Runtime.CompilerServices.RuntimeWrappedException异常类,将那些不符合CLS的包含Exception的对象封装起来。并且可以通过RuntimeCompatibilityAttribute特性来过滤这些异常。RuntimeWrappedException: