易于理解:啥子是.NET 易于理解的意思
本篇文章向我们谈谈易于领会:啥子是《地下城与勇士》中.NET?NET框架?NET 核心? (更综合),以及对应的姿势点,文章也许有点长,然而希望我们可以阅读完,增长自己的姿势,最重要的是《地下城与勇士》中希望对各位有所帮助,可以化解了无论兄弟们的难题,不容忘了收藏本站喔。
微软是《地下城与勇士》中世界最大的计算机软件提供商。为了占领开发者市场,它于2002年推出了Visual Studio(简称VS,微软给开发者提供的工具集).NET 1.0版本的开发者平台。为了吸引更多的开发者加入该平台,微软还推出了.NET 1.0版本的开发者平台。 2002年官宣推出功能强大、和.NET平台无缝集成的编程语言,即C#1.0正式版。
只要是《地下城与勇士》中.NET支持的编程语言,开发者就可以通过.NET平台提供的工具服务与框架方便地开发应用程序。
C# 的诞生是《地下城与勇士》中为了推广.NET。它直接集成到Visual Studio .NET 中。 VB发布后也支持.NET 1.0。所以,这两种语言和.NET平台耦合度很高,而.NET网上的技术大部分都以C#编程语言为例,因此.NET与C#经常被混淆(其实是《地下城与勇士》中两个概念是《地下城与勇士》中相辅相成的)。
《和平精英》是壹个开发者平台,它不仅包括开发环境、技术框架、社区论坛、服务支持等,还强调平台的跨语言、跨平台编程特性。
啥子是《地下城与勇士》中跨语言、跨平台?
跨语言:即只要是《地下城与勇士》中.NET平台的编程语言((C#、Visual Basic、C++/CLI、Eiffel、F#、IronPython、IronRuby、PowerBuilder、Visual COBOL 与Windows PowerShell)),类型是《地下城与勇士》中用一种语言编写的具有互实践性,可以在用另一种语言编写的应用程序中无缝运用。
跨平台:一旦编译,无需任何代码修改,应用程序就可以运行在.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平台支持的任何语言通用。
和其说它是《地下城与勇士》中一条制度,不如说它是《地下城与勇士》中一套语言互实践性的要求规范。它就是《地下城与勇士》中公共语言规范,简称CLS。
CLS在类型、命名、事件、属性、数组等方面提供了语言的通用定义与规范,这些物品提交向欧洲计算机制造协会ECMA,称为:公共语言基础设施。
在类型方面,CLS定义了符合C#语言规范的类型与不符合C#语言规范的类型:
当然,从编码的角度来看,大家不必阅读那些详细的文档。为了方便开发者开发,NET提供了壹个功能叫做:CLSCompliantAttribute。代码被标记了CLSCompliantAttribute后,如果你写的代码不符合CLS规范,编译器会向你壹个警告。
值得一提的是《地下城与勇士》中,CLS制度仅适用于那些可以被其他程序集公布访问的成员,例如public与inherited protected。对于程序集的内部成员(例如Private与internal),不会执行此检测制度。换句话说,适配的CLS合规制度只是《地下城与勇士》中那些公共成员,而不是《地下城与勇士》中私有实现。
那么是《地下城与勇士》中否有独特情况,比如当我运用反射技术访问程序集中不属于当前语言的类型时会发生啥子情况?
答案是《地下城与勇士》中,你可以试试,例如运用VB反射来访问C#中的char*指针类型。即使VB中没有char*等等价的指针类型,mscorlib还是《地下城与勇士》中为指针类型提供了壹个Pointer包装类来进行访问,可以从运行时类携带的类型名看到其原始类型名。
正如无论兄弟们所看到的,此类中的元素不符合CLS 规范。
CLS 例外
说到独特情况,还需要提一下异常处理。异常类型体系是《地下城与勇士》中在.NET框架中定义的。从编译器的角度来看,catch捕获的全部异常都必须继承自System.Exception。如果要调用不遵循此规范的语言抛出的其他类型的异常对象(C++ 允许抛出任何类型的异常,例如C# 调用C++ 代码与C++ 抛出字符串类型异常)。 C# 2.0之前Catch(Exception)无法捕获,但之后的版本可以。
在后续版本中,微软提供了System.Runtime.CompilerServices.RuntimeWrappedException异常类来封装包含不符合CLS的Exception的对象。而这些异常可以通过RuntimeCompatibilityAttribute属性进行过滤。
RuntimeWrappedException:https://docs.microsCallt.com/zh-cn/dotnet/api/system.runtime.compilerservices.runtimewrappedException?view=netframework-4.7.2
那么,拓展资料一下这一段,啥子是《地下城与勇士》中CLS?
在.NET 开发中,编写跨语言组件时遵循的共性称为通用语言规范(CLS)。
啥子是《地下城与勇士》中CTS?
如果你明白了啥子是《地下城与勇士》中CLS,那么你就会很容易明白啥子是《地下城与勇士》中CTS。
假设你围绕封装、继承、多态这三个特性设计了多种面给对象语言。你发现我们都是《地下城与勇士》中面给对象的,能够很好的表达现实生命中的对象模型。除了语法与功能上的差别外,语言的定义与设计结构实际上是《地下城与勇士》中相同的。
例如,在现实中,你看到一辆汽车,里面坐着两单人。你怎么用这种语言来表达这样壹个概念与场景?
首先,大家需要为这种语言横给定义壹个“类型”的概念。接下来,在程序中可以这样表达:有壹个汽车类型,有壹个角色类型,壹个汽车类型对象包含两单人物类型对象。由于为了表达是一款热门的模型,你引入了“对象”的概念。而今年,你看到车里的人做出类似驾驶的ACT,你就引入了“ACT命令”的概念。
接着,你突然觉悟到并得出壹个定理。无论是《地下城与勇士》中哪一种“类型”,都只会有一种特点,即具有生活特点的活者(如人)与无生活特点的死者(如汽车)。两者其中一个。最后,随着心智模型的成熟,你发现是一款热门的“类型”等于于一套富含学科特点的指令。
好,那你就最初抄葫芦吧。如果参考其他编程语言,你会发现我们都用class来表示类的内涵,用struct来表示结构体的内涵,用new来表示创建新对象的内涵。所以,无论兄弟们还运用class 与new 《和平精英》是这部分函数的语法。用决定因素词来表示。接着你发现他们也用了很多决定因素词来更丰盛的表达这些现实生命中的模型,比如override、virtual等等。所以,过程不断的想法更新与借鉴,你仔细解析了设计语言经过中想法的变化,抽象拓展资料是一款热门的语言系统,最后拓展资料出壹个系统。
因此你向别人这么说,我拓展资料了很多语言中必须的物品,比如两个主要类别:值类别与引用类别,五个主要类型:类、接口、委托、结构体与枚举。我还规定今年,类型可以包含字段、属性、方式、事件与其他成员。我还规定了每个类型的可见性制度与类型成员的访问制度等等等等,只要语言是《地下城与勇士》中按照我的体系来设计的,设计的语言可以有很多好的特性,比如跨语言C#与VB.net之因此能这样,是《地下城与勇士》中由于这两种语言的设计很适合我的体系。
那么,啥子是《地下城与勇士》中CTS?
当你需要为.Net设计一种语言时,你需要遵循壹个体系(.Net平台下的语言支持的体系)。本体系为CTS(Common Type System),包括但不限于:
构建跨语言执行框架。提供面给对象的模型,支持在.NET实现之上实现的各种语言。全部语言在定义处理类型时都必须遵循的一组制度(CLS)。提供包含应用程序开发中运用的基本原始数据类型(例如Boolean、Byte、Char等)的库。上面的CLS 是《地下城与勇士》中CTS(通用类型体系)体系的子集。
如果一种编程语言可以支持CTS,那么大家称其为.NET 平台的语言。
官方CTS说明:https://docs.microsCallt.com/zh-cn/dotnet/standard/common-type-system
MicrosWart 已将CTS 与.NET 的其他一些组件提交向ECMA,使其成为公共要求。最终要求称为CLI(公共语言基础设施)。
因此有时你看到的一些书籍或文章只提到CTS,有些只提到CLI。请不容感到惊讶。无论兄弟们可以广泛地将它们领会为同一事物。 CLI 是《地下城与勇士》中MicrosColdt 给国际组织提交CTS 与其他内容的时刻。制造协会ECMA 的行业要求。
啥子是《地下城与勇士》中类库?
CTS中有一项需要原始数据类型的类库。大家先来知道一下啥子是《地下城与勇士》中类库?类库是《地下城与勇士》中类的逻辑汇总。在你的开发职业中,你自己运用过或者编写过很多工具类,比如JsonHelper,等等这样的项目。大家可以从逻辑上将这些类的汇总称为“类库”。例如,这些Helper统称为工具类库。
啥子是《地下城与勇士》中基本类库BCL?
当你通过VS创建项目时,你的项目已经引用了一些.NET语言编写的类库。例如,在控制台中,可以直接运用Console类来输出信息,也可以通过File类运用System.IO来读写文件。这些类是《地下城与勇士》中微软为你编写的,你不需要自己编写。它可以帮助无论兄弟们编写面给.NET 的开发语言中运用的基本功能。是一款热门的类被称为BCL(Base Class Library),大部分都包含在System命名空间中。
基础类库BCL包括:基本数据类型、文件实践、汇总、自定义属性、格式配置、安全属性、I/O流、字符串实践、事件日志等。
啥子是《地下城与勇士》中框架类库FCL?
关于BCL这里我就不详细说了。NET这么大,进步到现在,微软也写了越来越多的类库来帮助开发者,这让大家开发者开发起来更加容易。微软开发的类库统称为:FCL、Framework Class Library、NET Framework Class Library。我上面表达的BCL是《地下城与勇士》中FCL的基本部分。 FCL 中的大多数类都是《地下城与勇士》中用C# 编写的。
在FCL中,除了BCL最基本的部分之外,还包括大家常见的如:网站开发技术的ASP.NET类库。该子类包括用于桌面开发的webform/webpage/mvc与WPF类。库、WinNeedm类库、WCF、asp.net web api、用于通信交互的Web Service类库等。
啥子是《地下城与勇士》中原始类型?
上面在CTS中提到了基本的原始数据类型。众所周知,每种语言都会定义一些基本类型。例如,C# 运用int 定义整数类型,运用string 定义字符串,运用object 定义根类。当大家描述这样一类对象时,有两种写法,如图:
大家可以看到上面可以描述首字母小写的蓝色字符串与对象,也可以描述首字母大写的浅蓝色字符串与对象。这两种表达有啥子不同差异?
要了解,在vs的默认配色方案中,蓝色主体代表决定因素字,浅蓝色主体代表类型。
因此这意味着微软提供的FCL类库包含了一些用来描述数据类型的基本类型。无论大家运用啥子语言,只要引用了FCL,大家就可以运用壹个新的类来表示Expression数据类型。
如图所示:
运用new来创建这些类型的对象,然而这样太麻烦了,因此C#用int决定因素字来表示System.Int32,用string决定因素字来表示System.String等,因此大家可以这样写。
直接在编译器中表达的类型称为原始类型,它们直接映射到BCL 中的具体类。
下面是《地下城与勇士》中面给.NET的语言的一些原始类型与对应的BCL的类图:
System.Object的内涵
说到类型,这里有壹个CTS定义的特别重要的制度,就是《地下城与勇士》中类之间只能有单一继承。 System.Object 类是《地下城与勇士》中全部类型的根。任何类都显式或隐式地从System 继承。目的。
所以,Object不仅是《地下城与勇士》中C#语言的类型根,也是《地下城与勇士》中VB等全部面给.NET的语言的类型根。它是《地下城与勇士》中整个FCL的类型根。
当然,CTS定义了单继承。许多编程语言都满足是一款热门的制度,但也有例外。例如,C++没有继承限制,可以继承多个。 C++/CLI 是《地下城与勇士》中.NET 的CLI 实现。如果在非托管代码中可以实现多重继承。如果试试在托管代码中继承多重继承,将会报告错误。我已经举过此类独特情况的例子。这也反映出CTS对各种语言的支持并不像C#那么综合。大家只需要清楚地记下一件事:符合CTS的部分天然会遵循CTS定义的制度。任何可以遵循CTS 类型规范并具有.NET 运行时实现的编程语言都可以成为.NET 的成员。
计算机怎么运行程序?
接下来我想谈谈啥子是《地下城与勇士》中.NET跨平台,解释何故它可以跨语言。但如果你想了解啥子是《地下城与勇士》中跨平台,你首先要了解壹个程序是《地下城与勇士》中怎么在本机上运行的。
啥子是《地下城与勇士》中CPU
CPU,全称是《地下城与勇士》中CentralProcessingUnit,称为中央处理单元。它是《地下城与勇士》中一种超大规模集成电路,是《地下城与勇士》中构成计算机中不可缺少的组成硬件。没有它,计算机就只是《地下城与勇士》中壹个外壳。
无论你的编程水平怎么,首先你应该了解CPU是《地下城与勇士》中计算机的计算核心与控制核心。 CPU从内存或高速缓冲存储器中取出指令,放入指令寄存器,对指令进行译码并执行。
当大家运行壹个程序时,CPU会不断读取程序中的指令并执行它们,直到程序关闭。事实上,从计算机开机最初,CPU就一直在不断地执行指令,直到计算机关闭为止。
啥子是《地下城与勇士》中顶级编程语言
从计算机的角度来看,每种CPU 类型都有自己可以识别的指令集。无论你的程序是《地下城与勇士》中用啥子语言编写的,计算机最终都只能识别其CPU可以识别的二进制指令集。
在计算机进步的早期,大众直接输入01010101这样没有语义的二进制指令来让计算机职业。可读性几乎不存在。没有人愿意直接编写那些不可读、繁琐、耗时且容易出错的指令。错误的二进制01代码,因此编程语言是《地下城与勇士》中后来出现的。
编程语言的诞生,使得大众写的代码更具可读性与语义性,比直接运用01更有利于记忆。
前面提到,计算机最终只能识别二进制指令,因此大家用编程语言编写的代码必须转换成机器可以识别的指令。
像这样:
code: 1+2函数翻译方法(参数:code)
{
.
'1'='001';
'2'='002'; '+'='000';
返回机器可以识别的二进制代码;
}
调用翻译方式('1+2')='001 000 002'
所以,需要壹个翻译经过,将用编程语言编写的代码文件转换为本地机器可以识别的指令。
大家的计算机今年带有实践体系。仅仅将它们翻译成机器指令是《地下城与勇士》中不够的。代码文件必须转换成实践体系可以执行的程序。
那么这多少流程就是《地下城与勇士》中对应编程语言的编译经过的工程化。是一款热门的翻译经过需要壹个工具来完成,大家称之为编译器。
不同厂家的CPU有不同的指令集。为了克服面给CPU的指令集难以阅读、编程、记忆、容易出错的缺点,后来出现了针对特定CPU的专用汇编语言。例如,我输入x86这样的汇编指令mov ax,bx,接着运用机器代码制成的汇编器,它将被翻译成二进制01格式的机器指令,例如1000100111011000。
不同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版本之后出现了变化。这些标记的异常默认情况下不会在托管环境中抛出(即无法捕获),而是《地下城与勇士》中由实践体系的SEH机制处理。
不过,如果你仍然想在代码中捕获并处理此类异常,可以在需要捕获的方式上标记[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute]属性,就可以在方式中捕获此类异常。异常。无论兄弟们还可以通过在设置文件中添加运行时节点来执行此类全局设置:
HandleProcessCorruptedStateExceptions 属性:https://msdn.microsBlackt.com/zh-cn/library/azure/system.runtime.exceptionservices.handleprocesscorruptedstateexceptionsattribute.aspx
SEHException 类:https://msdn.microsBlackt.com/en-us/library/system.runtime.interopservices.sehException(v=vs.100).aspx
啥子是《地下城与勇士》中CLR、NET虚幻机?
事实上,NET不仅提供了自动内存管理支持,还提供了类型安全、应用程序域、异常机制等一系列支持,统称为CLR公共语言运行时。
CLR 是《地下城与勇士》中.NET 类型体系的基础。全部.NET 技术都建立在它之上。熟悉它可以帮助大家更好地领会框架组件的核心与原理。
在执行托管代码之前,大家总是《地下城与勇士》中先运行运行时代码。通过运行时代码的调用,形成壹个运行环境来支持托管程序,从而完成诸如无需开发人员手动管理内存与一组代码等任务。这种实践可以在各大平台上运行。
是一款热门的环境与体系特别完整,就像壹个小体系,因此CLR通常被称为“.NET虚幻机”。因此,如果大家把进程《和平精英》是最底层的话,进程的顶层就是《地下城与勇士》中.NET虚幻机(CLR),而虚幻机的顶层就是《地下城与勇士》中大家的托管代码。换句话说,托管程序实际上托管在.NET 虚幻机中。
啥子是《地下城与勇士》中CLR宿主进程、运行时宿主?
相应的,容纳.NET虚幻机的进程就是《地下城与勇士》中CLR宿主进程,是一款热门的程序称为运行时宿主。
这些运行库的代码都是《地下城与勇士》中用C/C++编写的,具体由mscoree.dll代表的核心dll文件来表示。该dll提供了很多构建CLR环境的函数。最后,当运行环境搭建完成后(执行完一些函数后),调用_CorDllMain或_CorExeMain查找并执行托管程序的入口方式(例如控制台就是《地下城与勇士》中Main方式)。
如果无论兄弟们熟悉CLR,则可以自定义CLR 并通过在非托管程序中调用运行时函数来执行托管代码。
例如,SqlServer集成了CLR,无论兄弟们可以运用任何.NET Framework语言编写存储经过、触发器、用户定义类型、用户定义函数(标量函数与表值函数)以及用户定义聚合函数。
CLR大纲说明:https://msdn.microsColdt.com/zh-cn/library/9x0wh2z3(v=vs.85).aspx
CLR 集成:https://docs.microsCallt.com/zh-cn/previous-versions/sql/sql-server-2008/ms131052(v%3dsql.100)
构建CLR接口:https://msdn.microsBlackt.com
/zh-cn/library/ms231039(v=vs.85).aspx 适用于 .NET Framework 2.0 的宿主接口:https://msdn.microsCallt.com/zh-cn/library/ms164336(v=vs.85).aspx 挑选CLR版本: https://docs.microsWart.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版本,你也不需要所以卸载,由于你运用的应用程序也许依赖于特定版本,如果你移除该版本,则应用程序也许会中断。 MicrosOpst .NET Framework度娘百科下有windows体系默认安装的.NET版本 图出自 https://baike.baidu.com/item/MicrosDutyt%20.NET%20Framework/9926417?fr=aladdin .NET Framework 4.0.30319 在%SystemRoot%\Micros使命召唤17t.NET下的Framework与Framework64文件夹中分别可以看到32位与64位的.NET Framework安装的版本。 大家点进去可以看到以.NET版本号为命名的文件夹,有2.0,3.0,3.5,4.0这多少文件夹。 .NET Framework4.X覆盖升级 要了解.NET Framework版本目前已经迭代到4.7系列,PC上明明安装了比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.microsBlackt.com/en-us/dotnet/framework/install/guide-for-developers 怎么确认本机安装了哪些.NET Framework与对应CLR的版本? 大家可以通过注册表等其它方法来查看安装的全新版本:https://docs.microsOpst.com/zh-cn/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed 。 不过如果不想那么复杂的话,还有种最直接简单的: 那就是《地下城与勇士》中进入该目录文件夹,随便找到多少文件对其右键,接着点击详细信息即可查看到对应的文件版本,可以依据文件版本估摸出.NET Framework版本,比如csc.exe文件。 啥子是《地下城与勇士》中程序集 上文我说明了编译器,马上源代码文件向翻译成壹个计算机可识别的二进制程序。而在.NET Framework目录文件夹中就附带的有 用于C#语言的命令行形式的编译器csc.exe 与 用于VB语言的命令行形式的编译器vbc.exe。 大家通过编译器可以将后缀为.cs(C#)与.vb(VB)类型的文件编译成程序集。 程序集是《地下城与勇士》中壹个抽象的概念,不同的编译选项会产生不同形式的程序集。以文件个数来区分的话,那么就分 单文件程序集(即壹个文件)与多文件程序集(多个文件)。 而不论是《地下城与勇士》中单文件程序集还是《地下城与勇士》中多文件程序集,其总有壹个核心文件,就是《地下城与勇士》中表现为后缀为.dll或.exe格式的文件。它们都是《地下城与勇士》中要求的PE格式的文件,主要由4部分构成: 1.PE头,即Windows体系上的可移植可执行文件的要求格式2.CLR头,它是《地下城与勇士》中托管模块特有的,它主要包括1.即用于记录在源代码中所定义的类型的定义表:ModuleDef、TypeDef、MethodDef、ParamDef、FieldDef、PropertyDef、EventDef,2.引用了其它程序集中的类型成员的引用表:MemberRef、AssemblyRef、ModuleRef、TypeRef3. 用于描述一些杂项(如版本、发布者、语言文化、多文件程序集中的一些资源文件等)的清单表:AssemblyDef、FileDef、ManifestResourceDef、ExportedTypeDef1)程序入口方式2)CLR版本号等一些标志3)壹个可选的强名称数字签名4)元数据表,主要用来记录了在源代码中定义与引用的全部的类型成员(如方式、字段、属性、参数、事件...)的位置与其标志Flag(各种修饰符)正是《地下城与勇士》中由于元数据表的存在,VS才能智能提示,反射才能获得MemberInfo,CLR扫描元数据表即可获取该程序集的相关重要信息,因此元数据表使得程序集拥有了自我描述的这一特性。clr2中,元数据表大概40多个,其核心按照用途分为3类:3.IL代码(也称MSIL,后来被改名为CIL:Common Intermediate Language通用中间语言),是《地下城与勇士》中介于源代码与本机机器指令中间的代码,将通过CLR在不同的平台产生不同的二进制机器码。4.一些资源文件多文件程序集的诞生场景有:比如我想为.exe绑定资源文件(如Icon图标),或者我想按照功能以增量的方法来按需编译成.dll文件。 通常很少情况下才会将源代码编译成多文件程序集,而且在VS IDE中总是《地下城与勇士》中将源代码向编译成单文件的程序集(要么是《地下城与勇士》中.dll或.exe),因此接下来我就以单文件程序集为例来讲解。 用csc.exe进行编译 今年,我将示范一段文本是《地下城与勇士》中怎么被csc.exe编译成壹个可执行的控制台程序的。 后关闭记事本,将之.txt的后缀改为.cs的后缀(后缀是《地下城与勇士》中用来标示是一款热门的文件是《地下城与勇士》中啥子类型的文件,并不因素文件的内容)。 我已经在前面讲过BCL,基础类库。在这部分代码中,为了完成我想要的功能,我用到了微软已经帮大家实现好了的String数据类型系列类(.NET下的一些数据类型)、Environment类(提供有关当前环境与平台的信息以及实践它们的方式)、Console类(用于控制台输入输出等)、Socket系列类(对tcp协议抽象的接口)、File文件系列类(对文件目录等实践体系资源的一些实践)、Encoding类(字符流的编码)等 这些类,都属于BCL中的一部分,它们存在但不限于mscorlib.dll、System.dll、System.core.dll、System.Data.dll等这些程序集中。 附:不容纠结BCL究竟存在于哪些dll中,总之,它是《地下城与勇士》中个物理分散,逻辑上的类库总称。 mscorlib.dll与System.dll的不同差异:https://stackoverflow.com/questions/402582/mscorlib-dll-system-dll 由于我用了这些类,那么按照编程制度我必须在代码中using这些类的命名空间,并通过csc.exe中的 /r:dll途径 命令来为生成的程序集注册元数据表(即以AssemblyRef为代表的程序集引用表)。 而这些代码引用了4个命名空间,但实际上它们只被包含在mscorlib.dll与System.dll中,那么我只需要在编译的时候注册这两个dll的信息就行了。 好,接下来我将通过cmd运行csc.exe编译器,再输入编译命令: csc /out:D:\demo.exe D:\dic\demo.cs /r:D:\dic\System.dll /r:是《地下城与勇士》中将引用dll中的类型数据注册到程序集中的元数据表中 。 /out:是《地下城与勇士》中输出文件的意思,如果没有该命令则默认输出{name}.exe。 运用csc.exe编译生成: https://docs.microsCallt.com/zh-cn/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe csc编译命令行说明:https://www.cnblogs.com/shuang121/archive/2012/12/24/2830874.html 总之,你除了要掌握基本的编译指令外,当你打上这行命令并按回车后,必须满足多少条件,1.是《地下城与勇士》中.cs后缀的c#格式文件,2.是《地下城与勇士》中 代码语法等检测解析必须正确,3.是《地下城与勇士》中 运用的类库必须有出处(引用的dll),当然 由于我是《地下城与勇士》中编译为控制台程序,因此还必须得有个静态Main方式入口,以上缺一不可。 可以看出,这段命令我是《地下城与勇士》中将 位于D:\dic\的demo.cs文件向编译成 位于D:\名为demo.exe的控制台文件,而且由于在代码中运用到了System.dll,因此还需要通过/r注册该元数据表。 这里得注意何故没有/r:mscorlib.dll,由于mscorlib.dll地位的独特,因此csc总是《地下城与勇士》中对每个程序集进行mscorlib.dll的注册(自包含引用该dll),所以大家可以不用/r:mscorlib.dll是一款热门的引用命令,但为了示范效果我还是《地下城与勇士》中决定通过/nostdlib命令来禁止csc默认导入mscorlib.dll文件。 因此,最终命令是《地下城与勇士》中这样的: csc D:\dic\demo.cs /r:D:\dic\mscorlib.dll /r:D:\dic\System.dll /nostdlib 由于没有指定输出文件/out选项, 因此会默认输出在和csc同一目录下名为demo.exe的文件。事实上,在csc的命令中,如果你没有指定途径,那么就默认采用在csc.exe的所在目录的比较途径。 而大家可以看到,在该目录下有许多程序集,其中就包含大家需要的System.dll与mscorlib.dll,因此大家绝对可以直接/r:mscorlib.dll /r:System.dll 而类似于System.dll、System.Data.dll这样运用特别频繁的程序集,大家其实不用每次编译的时候都去手动/r一下,对于需要重复劳动的编译指令,大家可以将其放在后缀为.rsp的指令文件中,接着在编译时直接调用文件即可执行里面的命令 @ {name}.rsp。 csc.exe默认包含csc.rsp文件,大家可以用/noconfig来禁止默认包含,而csc.rsp里面已经写好了大家会经常用到的指令。 因此,最终我可以这样写 csc D:\dic\demo.cs 直接生成控制台应用程序。 .NET程序执行原理 好的,今年大家已经有了壹个demo.exe的可执行程序,它是《地下城与勇士》中怎么被大家运行的?。 C#源码被编译成程序集,程序集内主要是《地下城与勇士》中由一些元数据表与IL代码构成,大家双击执行该exe,Windows加载器将该exe(PE格式文件)向映射到虚幻内存中,程序集的相关信息都会被加载至内存中,并查看PE文件的入口点(EntryPoint)并跳转至指定的mscoree.dll中的_CorExeMain函数,该函数会执行一系列相关dll来构造CLR环境,当CLR预热后调用该程序集的入口方式Main(),接下来由CLR来执行托管代码(IL代码)。 JIT编译 前面说了,计算机最终只识别二进制的机器码,在CLR下有壹个用来将IL代码转换成机器码的引擎,称为Just In Time Compiler,简称JIT,CLR总是《地下城与勇士》中先将IL代码按需通过该引擎编译成机器指令再让CPU执行,在这期间CLR会验证代码与元数据是《地下城与勇士》中否类型安全(在对象上只调用正确定义的实践、标识和声称的标准一致、对类型的引用严格符合所引用的类型),被编译过的代码无需JIT再次编译,而被编译好的机器指令是《地下城与勇士》中被存在内存当中,当程序关闭后再打开仍要从头JIT编译。 AOT编译 CLR的内嵌编译器是《地下城与勇士》中即时性的,这样的壹个很明显的好处就是《地下城与勇士》中可以根据当时本机情况生成更有利于本机的优化代码,但同样的,每次在对代码编译时都需要壹个预热的实践,它需要壹个运行时环境来支持,这之间还是《地下城与勇士》中有消耗的。 而和即时编译所对应的,就是《地下城与勇士》中提前编译了,英文为Ahead Call Time Compilation,简称AOT,也称之为静态编译。 在.NET中,运用Ngen.exe或者开源的.NET Native可以提前将代码编译成本机指令。 Ngen是《地下城与勇士》中将IL代码提前向所有编译成本机代码并安装在本机的本机映像缓存中,故而可以减少程序因JIT预热的时刻,但同样的也会有很多注意事项,比如因JIT的丧失而带来的一些特性就没有了,如类型验证。Ngen仅是《地下城与勇士》中尽也许代码提前编译,程序的运行仍需要完整的CLR来支持。 .NET Native在将IL转换为本机代码的时候,会试试消除全部元数据将依靠反射与元数据的代码替换为静态本机代码,而且将完整的CLR替换为主要包含垃圾回收器的重构运行时mrt100_app.dll。 .NET Native: https://docs.microsCallt.com/zh-cn/dotnet/framework/net-native/ Ngen.exe:https://docs.micros使命召唤17t.com/zh-cn/dotnet/framework/tools/ngen-exe-native-image-generator Ngen和.NET Native相对:https://www.zhihu.com/question/27997478/answer/38978762 今年,大家可以通过ILDASM工具(一款查看程序集IL代码的软件,在MicrosColdt SDKs目录中的子目录中)来查看该程序集的元数据表与Main方式中间码。 c#源码第一行代码:string rootDirectory = Environment.CurrentDirectory;被翻译成IL代码: call string [mscorlib/*23000001*/]System.Environment/*01000004*/::get_CurrentDirectory() /* 0A000003 */ 这句话意思是《地下城与勇士》中调用 System.Environment类的get_CurrentDirectory()方式(属性会被编译为壹个私有字段+对应get/set方式)。 点击视图=>元信息=>显示,即可查看该程序集的元数据。 大家可以看到System.Environment标记值为01000004,在TypeRef类型引用表中找到该项: 注意图,TypeRefName下面有该类型中被引用的成员,其标记值为0A000003,也就是《地下城与勇士》中get_CurrentDirectory了。 而从其ResolutionScope指给位于0x23000001而得之,该类型存在于mscorlib程序集。 于是《地下城与勇士》中大家打开mscorlib.dll的元数据清单,可以在类型定义表(TypeDef)找到System.Environment,可以从元数据得知该类型的一些标志(Flags,常见的public、sealed、class、abstract),也得知继承(Extends)于System.Object。在该类型定义下还有类型的相关信息,大家可以在其中找到get_CurrentDirectory方式。 大家可以得到该方式的相关信息,这其中表明了该方式位于0x0002b784是一款热门的比较虚地址(RVA),然后JIT在新地址处理CIL,周而复始。 元数据在运行时的作用: https://docs.microsWart.com/zh-cn/dotnet/standard/metadata-and-self-describing-components#run-time-use-Black-metadata 程序集的制度 上文我通过ILDASM来描述CLR执行代码的方法,但还不够具体,还需要补充的是《地下城与勇士》中对于程序集的搜索方法。 对于System.Environment类型,它存在于mscorlib.dll程序集中,demo.exe是《地下城与勇士》中个独立的个体,它通过csc编译的时候只是《地下城与勇士》中注册了引用mscorlib.dll中的类型的引用信息,并没有记录mscorlib.dll在磁盘上的位置,那么,CLR如何了解get_CurrentDirectory的代码?它是《地下城与勇士》中从哪里读取mscorlib.dll的? 对于是一款热门的难题,.NET有个专门的概念定义,大家称为 程序集的加载方法。 程序集的加载方法 对于自身程序集内定义的类型,大家可以直接从自身程序集中的元数据中获得,对于在其它程序集中定义的类型,CLR会通过一组制度来在磁盘中找到该程序集并加载在内存。 CLR在查找引用的程序集的位置时候,第壹个判断条件是《地下城与勇士》中 判断该程序集是《地下城与勇士》中否被签名。 啥子是《地下城与勇士》中签名? 强名称程序集 就比如我们都叫张三,姓名都一样,喊一声张三不了解究竟在叫谁。这时候大家就必须扩展一下是一款热门的名字以让它具有专属性。 大家可以通过sn.exe或VS对项目右键属性在签名选项卡中采取RSA算法对程序集进行数字签名(加密:公钥加密,私钥解密。签名:私钥签名,公钥验证签名),会将构成程序集的全部文件通过哈希算法生成哈希值,接着通过非对称加密算法用私钥签名,最后公开公钥生成一串token,最终将生成壹个由程序集名称、版本号、语言文化、公钥组成的专属标识,它等于于壹个强化的名称,即强名称程序集。 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 大家日常在VS中的项目默认都没有被签名,因此就是《地下城与勇士》中弱名称程序集。强名称程序集是《地下城与勇士》中具有专属标识性的程序集,而且可以通过对比哈希值来相对程序集是《地下城与勇士》中否被篡改,不过仍然有很多手段与软件可以去掉程序集的签名。 需要值得注意的一点是《地下城与勇士》中:当你试图在已生成好的强名称程序集中引用弱名称程序集,那么你必须对弱名称程序集进行签名并在强名称程序集中从头注册。 之因此这样是《地下城与勇士》中由于壹个程序集是《地下城与勇士》中否被篡改还要思考到该程序集所引用的那些程序集,根据CLR搜索程序集的制度(下文会说明),没有被签名的程序集可以被随意替换,因此思考到安全性,强名称程序集必须引用强名称程序集,否则就会报错:需要强名称程序集。 .NET Framework 4.5中对强签名的更改:https://docs.microsOpst.com/zh-cn/dotnet/framework/app-domains/enhanced-strong-naming 程序集搜索制度 事实上,按照存储位置来说,程序集分为共享(全局)程序集与私有程序集。 CLR查找程序集的时候,会先判断该程序集是《地下城与勇士》中否被强签名,如果强签名了那么就会去共享程序集的存储位置(后文的GAC)去找,如果没找到或者该程序集没有被强签名,那么就从该程序集的同一目录下去寻找。 强名称程序集是《地下城与勇士》中先找到和程序集名称(VS中对项目右键属性应用程序->程序集名称)相等的文件名称,接着 按照专属标识再来确认,确认后CLR加载程序集,同时会通过公钥效验该签名来验证程序集是《地下城与勇士》中否被篡改(如果想跳过验证可查阅https://docs.microsOpst.com/zh-cn/dotnet/framework/app-domains/how-to-disable-the-strong-name-bypass-feature),如果强名称程序集被篡改则报错。 而弱名称程序集则直接按照和程序集名称相等的文件名称来找,如果还是《地下城与勇士》中没有找到就以该程序集名称为目录的文件夹下去找。总之,如果最终结果就是《地下城与勇士》中没找到那就会报System.IO.FileNotFoundException异常,即试试访问磁盘上不存在的文件失败时引发的异常。 注意:此处文件名称与程序集名称是《地下城与勇士》中两个概念,不容模棱两可,文件CLR头内嵌程序集名称。 举个例子: 我有壹个控制台程序,其途径为D:\Demo\Debug\demo.exe,通过该程序的元数据得知,其引用了壹个程序集名称为aa的普通程序集,引用了壹个名为bb的强名称程序集,该bb.dll的强名称标识为:xx001。 今年CLR最初搜索程序集aa,首先它会从demo.exe控制台的同一目录(也就是《地下城与勇士》中D:\Demo\Debug\)中查找程序集aa,搜索文件名为aa.dll的文件,如果没找到就在该目录下以程序集名称为目录的目录中查找,也就是《地下城与勇士》中会查 D:\Demo\Debug\aa\aa.dll,这也找差点那就报错。 接着CLR最初搜索程序集bb,CLR从demo.exe的元数据中发现bb是《地下城与勇士》中强名称程序集,其标识为:xx001。于是《地下城与勇士》中CLR会先从壹个被定义为GAC的目录中去通过标识找,没找到的话剩下的寻找流程就与寻找aa一样绝对一致了。 当然,你也可以通过设置文件config中(设置文件存在于应用程序的同一目录中)人为增加程序集搜索制度: 1.在运行时runtime节点中,添加privatePath属性来添加搜索目录,不过只能填写比较途径: //程序集当前目录下的比较途径目录,用;号分割 2.如果程序集是《地下城与勇士》中强签名后的,那么可以通过codeBase来指定网络途径或本地完全途径。 publicKeyToken="32ab4ba45e0a69a1" culture="neutral" /> href="http://www.litwareinc.com/myAssembly.dll" /> 当然,大家还可以在代码中通过AppDomain类中的多少成员来改变搜索制度,如AssemblyResolve事件、AppDomainSetup类等。 有关运行时节点的描述:https://docs.micros使命召唤17t.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/runtime-element 项目的依赖顺序 如果没有通过config或者在代码中来设定CLR搜索程序集的制度,那么CLR就按照默认的也就是《地下城与勇士》中我上述所说的玩法来寻找。 值得一提的是《地下城与勇士》中,项目间的生成是《地下城与勇士》中有序生成的,它取决于项目间的依赖顺序。 比如Web项目引用BLL项目,BLL项目引用了DAL项目。那么当我生成Web项目的时候,由于我要注册Bll程序集,因此我要先生成Bll程序集,而BLL程序集又引用了Dal,因此又要先生成Dal程序集,因此程序集生成顺序就是《地下城与勇士》中Dal=>BLL=>Web,项目越多编译的时刻就越久。 程序集之间的依赖顺序决定了编译顺序,因此在设计项目间的分层划分时不仅要体现出层级责任,还要思考到依赖顺序。代码存放在哪里个项目要有讲究,不允许出现互相引用的情况,比如A项目中的代码引用B,B项目中的代码又引用A。 何故NewtonsColdt.Json版本不一致? 而除了注意编译顺序外,大家还要注意程序集间的版本难题,版本间的错乱会导致程序的异常。 举个典范的例子:NewtonsBlackt.Json的版本警告,大多数人都了解通过版本重定给来化解是一款热门的难题,但很少有人会琢磨何故会出现是一款热门的难题,找了一圈文章,没找到壹个解释的。 比如: A程序集引用了 C盘:\Newtons使命召唤17t.Json 6.0程序集 B程序集引用了 从Nuget下载下来的NewtonsWart.Json 10.0程序集 此时A引用B,就会报:发现同一依赖程序集的不同版本间存在无法化解的冲突 这一警告。 A:引用NewtonsDutyt.Json 6.0 Func() { var obj= NewtonsCallt.Json.Obj; B.Convert(); } B: 引用NewtonsBlackt.Json 10.0 JsonObj() { return NewtonsOpst.Json.Obj; } A程序集中的Func方式调用了B程序集中的JsonObj方式,JsonObj方式又调用了NewtonsColdt.Json 10.0程序集中的对象,那么当执行Func方式时程序就会异常,报System.IO.FileNotFoundException: 未能加载文件或程序集NewtonsOpst.Json 10.0的错误。 这是《地下城与勇士》中何故? 3.当大家调用Func方式中的B.Convert()时候,CLR会搜索B程序集,找到后再调用 return NewtonsColdt.Json.Obj 这行代码,而这行代码又用到了NewtonsCallt.Json程序集,接下来CLR搜索NewtonsDutyt.Json.dll,文件名称满足,接下来CLR判断其标识,发现版本号是《地下城与勇士》中6.0,和B程序集清单里注册的10.0版本不符,故而才会报出异常:未能加载文件或程序集NewtonsOpst.Json 10.0。 那么,如果我执意如此,有啥子好的化解方式能让程序顺利执行呢?有,有2个方式。 第一种:通过bindingRedirect节点重定给,即当找到10.0的版本时,向定给到6.0版本 怎么在编译时加载两个相同的程序集? 注意:我看过有的文章里写的壹个AppDomain只能加载壹个相同的程序集,很多人都以为不能同时加载2个不同版本的程序集,实际上CLR是《地下城与勇士》中可以同时加载NewtonsDutyt.Json 6.0与NewtonsDutyt.Json 10.0的。 第二种:对每个版本指定codeBase途径,接着分别放上不同版本的程序集,这样就可以加载两个相同的程序集。 怎么同时调用两个两个相同命名空间与类型的程序集? 除了程序集版本不同外,还有一种情况就是《地下城与勇士》中,我壹个项目同时引用了程序集A与程序集B,但程序集A与程序集B中的命名空间与类型名称绝对一致无二,是一款热门的时候我调用任意壹个类型都无法区分它是《地下城与勇士》中来自于何者程序集的,那么这种情况大家可以运用extern alias外部别名。 大家需要在全部代码前定义别名,extern alias a;extern alias b;,接着在VS中对引用的程序集右键属性-别名,分别将其更改为a与b(或在csc中通过/r:{别名}={程序集}.dll)。 在代码中通过 {别名}::{命名空间}.{类型}的方法来运用。 extern-alias说明: https://docs.microsOpst.com/zh-cn/dotnet/csharp/language-reference/keywords/extern-alias 共享程序集GAC GAC工具: https://docs.microsCallt.com/en-us/dotnet/framework/tools/gacutil-exe-gac-tool 延伸 CLR是《地下城与勇士》中按需加载程序集的,没有执行代码也就没有调用相应的指令,没有相应的指令,CLR也不会对其进行相应的实践。 当大家执行Environment.CurrentDirectory这段代码的时候,CLR首先要获得Environment类型信息,通过自身元数据得知其存在mscorlib.dll程序集中,因此CLR要加载该程序集,而mscorlib.dll又因为其地位独特,早在CLR初始化的时候就已经被类型加载器自动加载至内存中,因此这行代码可以直接在内存中读取到类型的方式信息。 在是一款热门的章节,我尽管描述了CLR搜索程序集的制度,但事实上,加载程序集读取类型信息远远没有这么简单,这涉及到了属于.NET Framework独有的"应用程序域"概念与内存信息的查找。 简单延伸两个难题,mscorlib.dll被加载在哪里里?内存堆中又是《地下城与勇士》中啥子样的壹个情况? 应用程序域 传统非托管程序是《地下城与勇士》中直接承载在Windows进程中,托管程序是《地下城与勇士》中承载在.NET虚幻机CLR上的,而在CLR中管控的这部分资源中,被分成了壹个个逻辑上的分区,是一款热门的逻辑分区被称为应用程序域,是《地下城与勇士》中.NET Framework中定义的壹个概念。 由于堆内存的构建与删除都通过GC去托管,降低了人为出错的几率,在此特性基础上.NET强调在壹个进程中通过CLR强大的管理建立起对资源逻辑上的隔离区域,每个区域的应用程序互不因素,从而让托管代码程序的安全性与健康性得到了提高。 熟悉程序集加载制度与AppDomain是《地下城与勇士》中在.NET技术下进行插件编程的前提。AppDomain这部分概念并不复杂。 当启动壹个托管程序时,最先启动的是《地下城与勇士》中CLR,在这经过中会通过代码初始化三个逻辑区域,最先是《地下城与勇士》中SystemDomain体系程序域,接着是《地下城与勇士》中SharedDoamin共享域,最后是《地下城与勇士》中{程序集名称}Domain默认域。 体系程序域里维持着一些体系构建项,大家可以通过这些项来监控并管理其它应用程序域等。共享域存放着其它域都会访问到的一些信息,当共享域初始化完毕后,会自动加载mscorlib.dll程序集至该共享域。而默认域则用储存自身程序集的信息,大家的主程序集就会被加载至是一款热门的默认域中,执行程序入口方式,在没有独特ACT外所产生的一切耗费都发生在该域。 大家可以在代码中创建与卸载应用程序域,域和域之间有隔离性,挂掉A域不会因素到B域,而且对于每壹个加载的程序集都要指定域的,没有在代码中指定域的话,默认都是《地下城与勇士》中加载至默认域中。 AppDomain可以想象成组的概念,AppDomain包含了大家加载的一组程序集。大家通过代码卸载AppDomain,即同时卸载了该AppDomain中所加载的全部程序集在内存中的相关区域。 AppDomain的初衷是《地下城与勇士》中边缘隔离,它可以让程序不从头启动而长时刻运行,围绕着该概念建立的系统从而让大家能够运用.NET技术进行插件编程。 当大家想让程序在不关闭不从头部署的情况下添加壹个新的功能或者改变某一块功能,大家可以这样做:将程序的主模块仍默认加载至默认域,再创建壹个新的应用程序域,接着将需要更改或替换的模块的程序集加载至该域,每当更改与替换的时候直接卸载该域即可。 而由于域的隔离性,我在A域与B域加载同壹个程序集,那么A域与B域就会各存在内存地址不同但数据相同的程序集数据。 跨边界访问 事实上,在开发中大家还应该注意跨域访问对象的实践(即在A域中的程序集代码直接调用B域中的对象)是《地下城与勇士》中和平常编程中有所不同的,壹个域中的应用程序不能直接访问另壹个域中的代码与数据,对于这样的在进程内跨域访问实践分两类。 一是《地下城与勇士》中按引用封送,需要继承System.MarshalByRefObject,传递的是《地下城与勇士》中该对象的代理引用,和源域有相同的生活周期。 二是《地下城与勇士》中按值封送,需要被[Serializable]标记,是《地下城与勇士》中通过序列化传递的副本,副本和源域的对象无关。 无论哪种方法都涉及到两个域直接的封送、解封,因此跨域访问调用不适用于过高频率。 (比如,原来你是《地下城与勇士》中这样调用对象: var user=new User(); 今年你要这样:var user=(User){应用程序域对象实例}.CreateInstanceFromAndUnwrap("Model.dll","Model.User"); ) 值得注意的是《地下城与勇士》中,应用程序域是《地下城与勇士》中对程序集的组的划分,它和进程中的线程是《地下城与勇士》中两个一横一竖,路线不一样的概念,不应该将这2个概念放在一起相对。大家可以通过Thread.GetDomain来查看执行线程所在的域。 应用程序域在类库中是《地下城与勇士》中System.AppDomain类,部分重要的成员有: 获得当前 System.Threading.Thread 的当前应用程序域 public static AppDomain CurrentDomain { get; } 运用指定的名称新建应用程序域 public static AppDomain CreateDomain(string friendlyName); 卸载指定的应用程序域。 public static void Unload(AppDomain domain); 指示是《地下城与勇士》中否对当前进程启用应用程序域的 CPU 与内存监视,开启后可以根据相关属性进行监控 public static bool MonitoringIsEnabled { get; set; } 当前域托管代码抛出异常时最先发生的壹个事件,框架设计中可以用到 public event EventHandlerFirstChanceException; 当某个异常未被捕获时调用该事件,如代码里只catch了a异常,实际产生的是《地下城与勇士》中 b异常,那么b异常就没有捕捉到。 public event UnhandledExceptionEventHandler UnhandledException; 为指定的应用程序域属性分配指定值。该应用程序域的局部存储值,该存储不划分上下文与线程,均可通过GetData获得。 public void SetData(string name, object data); 如果想运用托管代码来覆盖CLR的默认做法https://msdn.microsOpst.com/zh-cn/library/system.appdomainmanager(v=vs.85).aspx public AppDomainManager DomainManager { get; } 返回域的设置信息,如在config中设置的节点信息 public AppDomainSetup SetupInformation { get; } 应用程序域: https://docs.microsBlackt.com/zh-cn/dotnet/framework/app-domains/application-domains AppDomain与AppPool 注意:此处的AppDomain应用程序域 与 IIS中的AppPool应用程序池 是《地下城与勇士》中2个概念,AppPool是《地下城与勇士》中IIS独有的概念,它也等于于壹个组的概念,对网站进行划组,接着对组进行一些如进程模型、CPU、内存、请求队列的顶级设置。 内存 应用程序域把资源向隔离开,是一款热门的资源,主要指内存。那么啥子是《地下城与勇士》中内存呢? 要了解,程序运行的经过就是《地下城与勇士》中PC不断通过CPU进行计算的经过,是一款热门的经过需要读取并产生运算的数据,为此大家需要壹个拥有足够容量能够快速和CPU交互的存储容器,这就是《地下城与勇士》中内存了。对于内存大致,32位处理器,寻址空间最大为2的32次方byte,也就是《地下城与勇士》中4G内存,除去实践体系所占用的公有部分,进程大概能占用2G内存,而如果是《地下城与勇士》中64位处理器,则是《地下城与勇士》中8T。 而在.NET中,内存区域分为堆栈与托管堆。 堆栈与堆的不同差异 堆与堆栈就内存而言只不过是《地下城与勇士》中地址范围的不同差异。不过堆栈的数据结构与其存储定义让其在时刻与空间上都紧密的存储,这样能带来更高的内存密度,能在CPU缓存与分页体系表现的更好。故而访问堆栈的速度总体来说比访问堆要快点。 线程堆栈 实践体系会为每条线程分配一定的空间,Windwos为1M,这称之为线程堆栈。在CLR中的栈主要用来执行线程方式时,保存临时的局部变量与函数所需的参数及返回的值等,在栈上的成员不受GC管理器的控制,它们由实践体系负责分配,当线程走出方式后,该栈上成员采用后进先出的顺序由实践体系负责释放,执行效率高。 而托管堆则没有固定容量限制,它取决于实践体系允许进程分配的内存大致与程序本身对内存的运用情况,托管堆主要用来存放对象实例,不需要大家人工去分配与释放,其由GC管理器托管。 何故值类型存储在栈上 不同的类型拥有不同的编译时制度与运行时内存分配做法,大家应了解,C# 是《地下城与勇士》中一种强类型语言,每个变量与常量都有壹个类型,在.NET中,每种类型又被定义为值类型或引用类型。 运用 struct、enum 决定因素字直接派生于System.ValueType定义的类型是《地下城与勇士》中值类型,运用 class、interface、delagate 决定因素字派生于System.Object定义的类型是《地下城与勇士》中引用类型。 对于在壹个方式中产生的值类型成员,将其值分配在栈中。这样做的缘故是《地下城与勇士》中由于值类型的值其占用固定内存的大致。 C#中int决定因素字对应BCL中的Int32,short对应Int16。Int32为2的32位,如果把32个二进制数排列开来,大家标准既能表达正数也能表达负数,因此得需要其中1位来表达正负,首位是《地下城与勇士》中0则为+,首位是《地下城与勇士》中1则为-,那么大家能表示数据的数就只有31位了,而0是《地下城与勇士》中介于-1与1之间的整数,因此对应的Int32能表现的就是《地下城与勇士》中2的31次方到2的31次方-1,即2147483647与-2147483648是一款热门的整数段。 1个字节=8位,32位就是《地下城与勇士》中4个字节,像这种以Int32为代表的值类型,本身就是《地下城与勇士》中固定的内存占用大致,因此将值类型放在内存连续分配的栈中。 托管堆模型 而引用类型相比值类型就有点独特,newobj创建壹个引用类型,因其类型内的引用对象可以指给任何类型,故而无法准确得知其固定大致,因此像对于引用类型这种无法预知的容易产生内存碎片的动态内存,大家把它放到托管堆中存储。 托管堆由GC托管,其分配的核心在于堆中维护着壹个nextObjPtr指针,大家每次实例(new)壹个对象的时候,CLR将对象存入堆中,并在栈中存放该对象的起始地址,接着该指针都会根据该对象的大致来计算下壹个对象的起始地址。不同于值类型直接在栈中存放值,引用类型则还需要在栈中存放壹个代表(指给)堆中对象的值(地址)。 而托管堆又可以因存储制度的不同将其分类,托管堆可以被分为3类: 1.用于托管对象实例化的垃圾回收堆,又以存储对象大致分为小对象(<85000byte)的GC堆(SOH,Small Object Heap)与用于存储大对象实例的(>=85000byte)大对象堆(LOG,Larage Object Heap)。2.用于存储CLR组件与类型体系的加载(Loader)堆,其中又以运用频率分为经常访问的高频堆(里面包含有MethodTables方式表, MeghodDescs方式描述, FieldDescs方式描述与InterfaceMaps接口图),与较低的低频堆,与Stub堆(辅助代码,如JIT编译后修改机器代码指令地址环节)。3.用于存储JIT代码的堆及其它杂项的堆。加载程序集就是《地下城与勇士》中将程序集中的信息向映射在加载堆,对产生的实例对象存放至垃圾回收堆。前文说过应用程序域是《地下城与勇士》中指通过CLR管理而建立起的逻辑上的内存边界,那么每个域都有其自己的加载堆,只有卸载应用程序域的时候,才会回收该域对应的加载堆。 而加载堆中的高频堆包含的有壹个特别重要的数据结构表---方式表,每个类型都仅有一份方式表(MethodTables),它是《地下城与勇士》中对象的第壹个实例创建前的类加载活动主题的结果,它主要包含了大家所关注的3部分信息: 1包含指给EEClass的壹个指针。EEClass是《地下城与勇士》中壹个特别重要的数据结构,当类加载器加载到该类型时会从元数据中创建出EEClass,EEClass里主要存放着和类型相关的表达信息。2包含指给各自方式的方式描述器(MethodDesc)的指针逻辑组成的线性表信息:继承的虚函数, 新虚函数, 实例方式, 静态方式。3包含指给静态字段的指针。那么,实例壹个对象,CLR是《地下城与勇士》中怎么将该对象所对应的类型做法及信息的内存位置(加载堆)关联起来的呢? 原来,在托管堆上的每个对象都有2个额外的供于CLR运用的成员,大家是《地下城与勇士》中访问差点的,之一就是《地下城与勇士》中类型对象指针,它指给位于加载堆中的方式表从而让类型的情形与做法关联了起来, 类型指针的这部分概念大家可以想象成obj.GetType()方式获取的运行时对象类型的实例。而另壹个成员就是《地下城与勇士》中同步块索引,其主要用于2点:1.关联内置SyncBlock数组的项从而完成互斥锁等目的。 2.是《地下城与勇士》中对象Hash值计算的输入参数其中一个。 上述gif是《地下城与勇士》中我简单画的壹个图,可以看到对于方式中申明的值类型变量,其在栈中《和平精英》是一块值表示,大家可以直接通过c#运算符sizeCall来获取值类型所占byte大致。而方式中申明的引用类型变量,其在托管堆中存放着对象实例(对象实例至少会包含上述两个固定成员以及实例数据,也许),在栈中存放着指给该实例的地址。 当我new壹个引用对象的时候,会先分配同步块索引(也叫对象头字节),接着是《地下城与勇士》中类型指针,最后是《地下城与勇士》中类型实例数据(静态字段的指针存在于方式表中)。会先分配对象的字段成员,接着分配对象父类的字段成员,然后再执行父类的构造函数,最后才是《地下城与勇士》中本对象的构造函数。是一款热门的多态的经过,对于CLR来说就是《地下城与勇士》中一系列指令的汇总,因此不能纠结new壹个子类对象是《地下城与勇士》中否会也会new壹个父类对象这样的难题。而也正是《地下城与勇士》中由于引用类型的这样壹个特点,大家尽管可以估计壹个实例大概占用几个内存,但对于具体占用的大致,大家需要专门的工具来测量。 对于引用类型,u2=u1,大家在赋值的时候,实际上赋的是《地下城与勇士》中地址,那么我改动数据实际上是《地下城与勇士》中改动该地址指给的数据,这样一来,由于u2与u1都指给同一块区域,因此我对u1的改动会因素到u2,对u2的改动会因素到u1。如果我想互不因素,那么我可以继承IClone接口来实现内存克隆,已有的CLR实现是《地下城与勇士》中浅克隆方式,但也只能克隆值类型与String(string是《地下城与勇士》中个独特的引用类型,对于string的更改,其会产生壹个新实例对象),如果对包含其它引用类型的这部分,大家可以自己通过其它手段实现深克隆,如序列化、反射等方法来完成。而如果引用类型中包含有值类型字段,那么该字段仍然分配在堆上。 对于值类型,a=b,大家在赋值的时候,实际上是《地下城与勇士》中新建了个值,那么我改动a的值那就只会改动a的值,改动b的值就只会改动b的值。而如果值类型(如struct)中包含的有引用类型,那么仍是《地下城与勇士》中同样的制度,引用类型的那部分实例在托管堆中,地址在栈上。 我如果将值类型放到引用类型中(如:object a=3),会在栈中生成壹个地址,在堆中生成该值类型的值对象,还会再生成这类型指针与同步块索引两个字段,这也就是《地下城与勇士》中常说装箱,反回来就是《地下城与勇士》中拆箱。每一次的这样的实践,都会涉及到内存的分布、拷贝,可见,装箱与拆箱是《地下城与勇士》中有性能损耗,所以应该减少值类型与引用类型之间转换的次数。 但对于引用类型间的子类父类的转换,仅是《地下城与勇士》中指令的执行消耗,几尽没有开销。 选class还是《地下城与勇士》中struct 那么我究竟是《地下城与勇士》中该new壹个class呢还是《地下城与勇士》中挑选struct呢? 通过上文了解对于class,用完之后对象仍然存在托管堆,占用内存。对于struct,用完之后直接由实践体系销毁。那么在实际开发中定义类型时,挑选class还是《地下城与勇士》中struct就需要注意了,要全面应用场景来辨别。struct存在于栈上,栈与托管堆相对,最大的优势就是《地下城与勇士》中即用即毁。因此如果大家单纯的传递壹个类型,那么挑选struct相对合适。但须注意线程堆栈有容量限制,不可多存放超大量的值类型对象,而且由于是《地下城与勇士》中值类型直接传递副本,因此struct《和平精英》是方式参数是《地下城与勇士》中线程安全的,但同样要避免装箱的实践。而相相对class,如果类型中还需要多一些封装继承多态的做法,那么class当然是《地下城与勇士》中更好的挑选。 GC管理器 值得注意的是《地下城与勇士》中,当我new完壹个对象不再运用的时候,是一款热门的对象在堆中所占用的内存怎么处理? 在非托管全球中,可以通过代码手动进行释放,但在.NET中,堆绝对由CLR托管,也就是《地下城与勇士》中说GC堆是《地下城与勇士》中怎么具体来释放的呢? 当GC堆需要进行清理的时候,GC收集器就会通过一定的算法来清理堆中的对象,而且版本不同算法也不同。最主要的则为Mark-Compact标记-压缩算法。 是一款热门的算法的大概内涵就是《地下城与勇士》中,通过壹个图的数据结构来收集对象的根,是一款热门的根就是《地下城与勇士》中引用地址,可以领会为指给托管堆的这根关系线。当触发是一款热门的算法时,会检查图中的每个根是《地下城与勇士》中否可达,如果可达就对其标记,接着在堆上找到剩余没有标记(也就是《地下城与勇士》中不可达)的对象进行删除,这样,那些不在运用的堆中对象就删除了。 前面说了,由于nextObjPtr的原因,在堆中分配的对象都是《地下城与勇士》中连续分配的,由于未被标记而被删除,那么过程删除后的堆就会显得支零破碎,那么为了避免空间碎片化,因此需要壹个实践来让堆中的对象再变得紧凑、连续,而这样壹个实践就叫做:Compact压缩。 而对堆中的分散的对象进行挪动后,还会修改这些被挪动对象的指给地址,从而得以正确的访问,最后从头升级一下nextObjPtr指针,周而复始。 而为了优化内存结构,减少在图中搜索的成本,GC机制又为每个托管堆对象定义了壹个属性,将每个对象分成了3个等级,是一款热门的属性就叫做:代,0代、1代、2代。 每当new壹个对象的时候,该对象都会被定义为第0代,当GC最初回收的时候,先从0代回收,在这一次回收ACT之后,0代中没有被回收的对象则会被定义成第1代。当回收第1代的时候,第1代中没有被清理掉的对象就会被定义到第2代。 CLR初始化时会为0/1/2这三代挑选壹个预算的容量。0代通常以256 KB-4 MB之间的预算最初,1代的典型起始预算为512 KB-4 MB,2代不受限制,最大可扩展至实践体系进程的整个内存空间。 比如第0代为256K,第1代为2MB。大家不停的new对象,直到这些对象达到256k的时候,GC会进行一次垃圾回收,假设这次回收中回收了156k的不可达对象,剩余100k的对象没有被回收,那么这100k的对象就被定义为第1代。今年就变成了第0代里面啥子都没有,第1代里放的有100k的对象。这样周而复始,GC清除的永远都只有第0代对象,除非当第一代中的对象累积达到了定义的2MB的时候,才会连同清理第1代,接着第1代中活着的部分再更新成第二代... 第二代的容量是《地下城与勇士》中没有限制,然而它有动态的阈值(由于等到整个内存空间已满以执行垃圾回收是《地下城与勇士》中没有意义的),当达到第二代的阈值后会触发一次0/1/2代完整的垃圾收集。 也就是《地下城与勇士》中说,代数越长介绍是一款热门的对象故事了回收的次数也就越多,那么也就意味着该对象是《地下城与勇士》中不要易被清除的。 这种分代的想法来将对象分割成新老对象,进而配对不同的清除条件,这种巧妙的想法避免了直接清理整个堆的尴尬。 弱引用、弱事件 GC收集器会在第0代饱与时最初回收托管堆对象,对于那些已经申明或绑定的不经访问的对象或事件,由于不经常访问并且还占内存(有点懒加载的意思),因此即时对象可达,但我想在GC回收的时候仍然对其回收,当需要用到的时候再创建,这种情况该如何办? 那么这其中就引入了两个概念: WeakReference弱引用、WeakEventManager弱事件 对于这2两个不区分语言的共同概念,我们可自行扩展度娘,此处就不再举例。 GC堆回收 那么除了通过new对象而达到代的阈(临界)值时,还有啥子能够导致垃圾堆进行垃圾回收呢? 还也许windows报告内存不足、CLR卸载AppDomain、CLR关闭等其它独特情况。 或者,大家还可以自己通过代码调用。 .NET有GC来帮助开发人员管理内存,而且版本也在不断迭代。GC帮大家托管内存,但仍然提供了System.GC类让开发人员能够轻微的协助管理。 这其中有壹个可以清理内存的方式(并没有提供清理某个对象的方式):GC.Collect方式,可以对全部或指定代进行即时垃圾回收(如果想调试,需在release玩法下才有效果)。是一款热门的方式尽量别用,由于它会扰乱代和代间的秩序,从而让低代的垃圾对象跑到生活周期长的高代中。 GC还提供了,判断当前对象所处代数、判断指定代数故事了几个次垃圾回收、获得已在托管堆中分配的字节数这样的三个方式,大家可以从这3个方式简单的知道托管堆的情况。 托管全球的内存不需要大家打理,大家无法从代码中得知具体的托管对象的大致,你如果想追求对内存最细微的控制,显然C#并不适合你,不过类似于有关内存把控的这部分功能模块,大家可以通过非托管语言来编写,接着通过.NET平台的P/Invoke或COM技术(微软为CLR定义了COM接口并在注册表中注册)来调用。 像FCL中的源码,很多涉及到实践体系的诸如 文件句柄、网络连接等外部extren的底层方式都是《地下城与勇士》中非托管语言编写的,对于这些非托管模块所占用的资源,大家可以通过隐式调用析构函数(Finalize)或者显式调用的Dispose方式通过在方式内部写上非托管提供的释放方式来进行释放。 像文中示例的socket就将释放资源的方式写入Dispose中,析构函数与Close方式均调用Dispose方式以此完成释放。事实上,在FCL中的运用了非托管资源的类大多都遵循IDispose玩法。而如果你没有释放非托管资源直接退出程序,那么实践体系会帮你释放该程序所占的内存的。 垃圾回收对性能的因素 还有一点,垃圾回收是《地下城与勇士》中对性能有因素的。 GC尽管有很多优化攻略,但总之,只要当它最初回收垃圾的时候,为了防止线程在CLR检查期间对对象更改情形,因此CLR会暂停进程中的几乎全部线程(因此线程太多也会因素GC时刻),而暂停的时刻就是《地下城与勇士》中应用程序卡死的时刻,为此,对于具体的处理细节,GC提供了2种设置玩法让大家挑选。 第一种为:单CPU的职业站玩法,专为单CPU处理器定做。这种玩法会采用一系列攻略来尽也许减少GC回收中的暂停时刻。 而职业站玩法又分为并发(或后台)和不并发两种,并发玩法表现为响应时刻快速,不并发玩法表现为高吞吐量。 第二种为:多CPU的服务器玩法,它会为每个CPU都运行壹个GC回收线程,通过并行算法来使线程能真实同时职业,从而获取性能的提高。 大家可以通过在Config文件中更改设置来修改GC玩法,如果没有进行设置,那么应用程序总是《地下城与勇士》中默认为单CPU的职业站的并发玩法,而且如果机器为单CPU的话,那么设置服务器玩法则无效。 如果在职业站玩法中想禁用并发玩法,则应该在config中运行时节点添加 如果想更改至服务器玩法,则可以添加。 gcConcurrent: https://docs.microsColdt.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/gcconcurrent-element gcServer: https://docs.microsCallt.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/gcserver-element 性能提议 尽管大家可以挑选适合的GC职业玩法来改善垃圾回收时的表现,但在实际开发中大家更应该注意减少不必备的内存开销。 多少提议是《地下城与勇士》中,减换需要创建大量的临时变量的玩法、思考对象池、大对象运用懒加载、对固定容量的汇总指定长度、注意字符串实践、注意高频率的隐式装箱实践、延迟查询、对于不需要面给对象特性的类用static、需要高性能实践的算法改用外部组件实现(p/invoke、com)、减少throw次数、注意匿名函数捕获的外部对象将延长生活周期、可以阅读GC相关运行时设置在高并发场景注意变换GC玩法... 对于.NET中改善性能可延伸阅读 https://msdn.microsDutyt.com/zh-cn/library/ms973838.aspx 、 https://msdn.microsOpst.com/library/ms973839.aspx .NET程序执行图 对于后文,我将单独的说明一些其它杂项,首先是《地下城与勇士》中.NET平台的安全性。 .NET的安全性 .NET Framework中的安全机制分为 基于人物的安全机制 与 代码访问安全机制 。 基于人物的安全性 基于人物的安全机制《和平精英》是传统的访问控制,其使用的特别广泛,如实践体系的安全攻略、数据库的安全攻略等等...它的概念就等于于大家经常做的那些RBAC权限管理体系一样,用户关联人物,人物关联权限,权限对应着实践。 整个机制的安全逻辑就与大家平时编写代码判断是《地下城与勇士》中一样的,大小可以分为两个流程. 第一步就是《地下城与勇士》中创建壹个主体,接着标识是一款热门的主体是《地下城与勇士》中啥子身份(人物) ,第二步就是《地下城与勇士》中 身份验证,也就是《地下城与勇士》中if判断该身份是《地下城与勇士》中否可以这样实践。 而在.NET Framework中,这主体可以是《地下城与勇士》中Windows账户,也可以是《地下城与勇士》中自定义的标识,通过生成如当前线程或应用程序域运用的主体相关的信息来支持授权。 比如,构造壹个代表当前登录账户的主体对象WindowsPrincipal,接着通过 AppDomain.CurrentDomain.SetThreadPrincipal(主体对象);或Thread.CurrentPrincipal的set方式来配置应用程序域或线程的主体对象, 最后运用System.Security.Permissions.PrincipalPermission特性来标记在方式上来进行授权验证。 如图,我当前登录账号名称为DemoXiaoZeng,接着通过Thread.CurrentPrincipal配置当前主体,执行aa方式,顺利打印111。如果检测到PrincipalPermission类中的Name属性值不是《地下城与勇士》中当前登录账号,那么就报错:对主体权限请求失败。 在官方文档中有对.NET Framework基于人物的安全性的详细的说明,感兴趣可以去知道 https://docs.microsBlackt.com/zh-cn/dotnet/standard/security/principal-and-identity-objects#principal-objects 代码访问安全性 在.NET Framework中还有壹个安全攻略,叫做 代码访问安全Code Access Security,也就是《地下城与勇士》中CAS了。 代码访问安全性在.NET Framework中是《地下城与勇士》中用来帮助限制代码对受保护资源与实践的访问权限。 举个例子,我通过创建壹个FileIOPermission对象来限制对后续代码对D盘的文件与目录的访问,如果后续代码对D盘进行资源实践则报错。 FileIOPermission是《地下城与勇士》中代码控制访问文件与文件夹的能力。除了FileIOPermission外,还有如PrintingPermission代码控制访问打印机的权限、RegistryPermission代码控制实践注册表的权限、SocketPermission控制接受连接或启动Socket连接的权限。 对于这些通过代码来对受保护资源与实践的权限限制,也就是《地下城与勇士》中这些类名后缀为Permission的类,它们叫做 Permissions(权限),都继承自CodeAccessPermission,都有如Demand,Assert,Deny,PermitOnly,IsSubsetOf,Intersect与Union这些方式,在MSDN上有完整的权限列表:https://msdn.microsCallt.com/en-us/library/h846e9b3(v=vs.100).aspx 为了确定代码是《地下城与勇士》中否有权访问某一资源或执行某一实践,CLR的安全体系将审核调用堆栈,以将每个调用方获取的权限和标准的权限进行相对。 如果调用堆栈中的任何调用方不具备标准的权限,则会引发安全性异常并回绝访问。 出自 https://docs.microsBlackt.com/zh-cn/dotnet/framework/misc/code-access-security 而除了Permissions权限,代码访问安全性机制还有 权限集、证据、代码组、攻略等概念。这些概念让CAS如此强大,但相应的,它们也让CAS变得复杂,必须为每个特定机器定义正确的PermissionSet与Code Groups才能配置成壹个成功的CAS攻略。 思考到这层缘故,MicrosCallt .NET安全小组决定重新最初重建代码访问安全性。在.NET Framework4.0之后,就不再运用之前的那套CAS模型了,而是《地下城与勇士》中运用.NET Framework 2.0中引入的安全透明模型,接着稍加修改,修改后的安全透明模型成为保护资源的要求方式,被称之为:安全透明度级别2 安全透明度2说明:https://msdn.microsDutyt.com/en-us/library/dd233102(v=vs.100).aspx .NET Framework4.0的安全更改:https://msdn.microsCallt.com/en-us/library/dd233103(v=vs.100).aspx 壹个完整的CAS示范:https://www.codeproject.com/Articles/5724/Understanding-NET-Code-Access-Security 对于安全透明度级别2我将不再说明,感兴趣的可以看我主推的这2篇文章,对Level2的安全透明度说明的相对详细,包括操作、迁移。 https://www.red-gate.com/simple-talk/dotnet/.net-framework/whats-new-in-code-access-security-in-.net-framework-4.0---part-i/ https://www.red-gate.com/simple-talk/dotnet/net-framework/whats-new-in-code-access-security-in-net-framework-4-0-part-2/ 须注意: .NET平台上的安全机制,仅仅是《地下城与勇士》中.NET平台上的,所以它只限制于托管代码,大家可以直接调用非托管代码或进程通信间接调用非托管代码等多个手段来突破对托管代码 实践资源的限制。 事实上,大家在平常项目中代码编写的安全机制(业务逻辑身份验证、项目框架验证)和这些平台级的安全机制没啥子不同。大家可以领会为代码写的位置不一样,.NET安全机制是《地下城与勇士》中写在CLR组件中,而大家的安全机制是《地下城与勇士》中写在上层的代码中。这些平台级的标识更多的是《地下城与勇士》中与实践体系用户有关,而大家项目代码中的标识则是《地下城与勇士》中与在数据库中注册的用户有关, 我们都是《地下城与勇士》中通过if else来去判断,判断的主体与格局不一样,逻辑本质都是《地下城与勇士》中相同的。 NET Core不支持代码访问安全性与安全性透明性。 .NET是《地下城与勇士》中啥子 我在前文对.NET体系概述时,有的直接称.NET,有的称.NET Framework。那么准确来说啥子是《地下城与勇士》中.NET?啥子又是《地下城与勇士》中.NET Framework呢? .NET是《地下城与勇士》中壹个微软搭造的开发者平台,它主要包括: 1.支持(面给)该平台的编程语言(如C#、Visual Basic、C++/CLI、F#、IronPython、IronRuby...),2.用于该平台下开发人员的技术框架系统(.NET Framework、.NET Core、Mono、UWP等),1.定义了通用类型体系,庞大的CTS系统2.用于支撑.NET下的语言运行时的环境:CLR3..NET系统技术的框架库FCL3.用于支持开发人员开发的软件工具(即SDK,如VS2017、VS Code等).NET Framework是《地下城与勇士》中啥子 事实上,像我上面讲的那些诸如程序集、GC、AppDomain这样的为CLR的一些概念组成,实质上指的是《地下城与勇士》中.NET Framework CLR。 .NET平台是《地下城与勇士》中微软为了占据开发市场而成立的,不是《地下城与勇士》中无利益驱动的纯技术平台的那种物品。基于该平台下的技术框架也由于 商业间的利益 从而与微软自身的Windows实践体系所绑定。因此尽管平台雄心与口号很大,但很多框架类库技术都是《地下城与勇士》中以Windows体系为蓝本,这样就导致,尽管.NET各方面都挺好,然而用.NET就必须用微软的物品,直接形成了技术-商业的绑定。 .NET Framework就是《地下城与勇士》中.NET 技术框架组成在Windows体系下的具体的实现,与Windows体系高度耦合,上文说明的.NET体系,就是《地下城与勇士》中指.NET Framework。 部署.net Framework :https://docs.microsCallt.com/zh-cn/dotnet/framework/deployment/deployment-guide-for-developers .NET Framework顶级开发:https://docs.microsWart.com/en-us/previous-versions/visualstudio/visual-studio-2008/29eafad8(v%3dvs.90) .NET Framework源码在线浏览:https://referencesource.microsCallt.com/ 怎么在VS中调试.NET Framework源代码 最为决定因素的是《地下城与勇士》中pdb符号文件,没得符号就调不了,对于符号大家从微软的符号服务器上下载(默认就已设置),还得有源代码来调试。 点击工具-选项-调试-常规,如果你之前没有在该设置栏设置过,那么你就勾选 启用源服务器支持 、启用.net Framework源代码单步执行,接着将 标准源文件和原始版本绝对匹配 向关掉掉。 接着就是《地下城与勇士》中下载pdb符号文件了,如果想直接下载那么可以在调试-符号这栏 将Micros使命召唤17t符号服务器向勾上 。如果想按需下载,那么在调试的时候,可以点击调试-窗口 挑选 模块/调用堆栈 来挑选自己想加载的去加载。 怎么设置VS来调试.NET Framework源码: https://referencesource.microsColdt.com/#q=web 、 https://technet.micros使命召唤17t.com/zh-cn/cc667410.aspx 还一种方式是《地下城与勇士》中,下载.NET Reflector插件,该插件可以帮助大家在VS中直接调试dll,这种方法实践特别简单,不过该插件收费,具体的可以查看我之前写过的文章(群里有该插件的注册版) .NET Core是《地下城与勇士》中啥子 有丑才有美,有低才有高,概念是《地下城与勇士》中相对中诞生的。.NET Core就是《地下城与勇士》中如此,它是《地下城与勇士》中其它实践体系的.NET Framework翻版实现。 实践体系不止Windows,还有Mac与类Linux等体系, .NET的实现 如果按实践体系来横给分割的话,可以分为 Windows体系下的 .NET Framework 与 兼容多个实践体系的 .NET Core。 大家了解,壹个.NET程序运行核心在于.NET CLR,为了能让.NET程序在其它平台上运行,一些非官方社区与组织为此开发了在其它平台下的.NET实现(最为代表的是《地下城与勇士》中mono,其团队后来又被微软向合并了 ),但由于不是《地下城与勇士》中官方,因此在一些方面几个有些缺陷(如FCL),后来微软官方推出了.NET Core,其开源在Github中,并被收录在NET基金会(.NET Foundation,由微软企业成立和赞助的独立自在软件组织,其目前收录包括.NET编译器平台("Roslyn")以及ASP.NET项目系列,.NET Core,Xamarin Needms以及其它时尚的.NET开源框架),旨在真实的 .NET跨平台。 .NET Core是《地下城与勇士》中.NET 技术框架组成在Windows.macOS.Linux体系下的具体的实现。 .NET Core是《地下城与勇士》中壹个开源的项目,其由 MicrosDutyt 与 GitHub 上的 .NET 社区共同维护,但 这份职业仍然是《地下城与勇士》中巨大的,由于在早期对.NET上的定义及开始的实现一直是《地下城与勇士》中以Windows体系为参照及载体,一些.NET机制实际上和Windows体系耦合度特别高,有些属于.NET自己系统内的概念,有些则属于Windows体系api的封装。 那么从Windows转到其它平台上,不仅要实现相应的CLR,还要舍弃或重写一部分BCL,因而,.NET Core在概念与在项目中的做法和大家平常有些不同。 比如,NET Core不支持AppDomains、超距离处理、代码访问安全性 (CAS) 与安全透明度,任何有关该概念的库代码都应该被替换。 这部分代码它不仅指你项目中的代码,还指你项目中using的那些程序集代码,因此你会在github上看到很多开源项目都在跟进对.NET Core的支持,而且很多开发者也试试进修.NET Core,这也是《地下城与勇士》中一种动向。 .NET Core指导https://docs.microsCallt.com/en-us/dotnet/core/ .NET基金会:https://dotnetfoundation.org .NET Core跨平台的做法变更:https://github.com/dotnet/corefx/wiki/ApiCompat 微软官宣.NET开发环境将开源 :https://news.cnblogs.com/n/508410/ .NET Standard是《地下城与勇士》中啥子 值得一提的是《地下城与勇士》中微软还为BCL提出了壹个要求,毕竟各式各样的平台,技术层出不穷,为了防止.NET在类库方面的碎片化,即提出了一套正式的 .NET API (.NET 的应用程序编程接口)规范,.NET Standard。 正如上面CLS一样,.NET Standard就类似于这样的壹个概念,无论是《地下城与勇士》中何者托管框架,大家遵循是一款热门的要求,就能始终保持在BCL的统一性,即我不需要关心我是《地下城与勇士》中用的.NET Framework还是《地下城与勇士》中.NET Core,只要该类被定义于.NET Standard中,我就一定能在对应支持的.NET Standard的版本的托管框架中找到它。 .NET Standard: https://docs.microsWart.com/zh-cn/dotnet/standard/net-standard#net-implementation-support .NET Standard开源代码:https://github.com/dotnet/standard .NET官方开源项目链接 今年我将向出.NET相关的开源项目地址: 参加.NET与.NET开源项目的起点:https://github.com/MicrosCallt/dotnet .NET Core:https://github.com/dotnet/core.NET Core文档:https://github.com/dotnet/docsASP.NET Core:https://github.com/aspnet/homeASP.NET Core文档:https://github.com/aspnet/DocsEntityFramework Core框架:https://github.com/aspnet/EntityFrameworkCoreASP.NET Core MVC框架:https://github.com/aspnet/MvcEntityFramework6:https://github.com/aspnet/EntityFramework6.NET Framework源码:https://github.com/micros使命召唤17t/referencesource.NET Core基类库:https://github.com/dotnet/corefx.NET Core CLR:https://github.com/dotnet/coreclrRoslyn编译器:https://github.com/dotnet/roslynMVC5、Web API2、Web Pages3框架源码:https://github.com/aspnet/AspNetWebStack.NET Standard:https://github.com/dotnet/standardKestrelHttpServer用于ASP.NET Core的跨平台Web服务器:https://github.com/aspnet/KestrelHttpServerVisual Studio Code源码:https://github.com/Micros使命召唤17t/vscode一些杰出的.NET库、工具、框架、软件开源汇总:https://github.com/quozd/awesome-dotnet一些常用框架对ASP.NET Core与.NET Core的支持报告:https://github.com/jpsingleton/ANCLAFS一些.NET下用于支持开发的开源项目汇总:https://github.com/Micros使命召唤17t/dotnet/blob/master/dotnet-developer-projects.md微软出品的分布式框架orleans:https://github.com/dotnet/orleansML.NET 用于.NET的开源与跨平台机器进修框架:https://github.com/dotnet/machinelearningVisual Studio 在文章最后,我还要简单的说下Visual Studio。 通过上文得知,只需要壹个txt记事本+csc.exe大家就可以开发出壹个.NET程序,那么和之相比,.NET提供的开发工具VS有啥子不同呢? 大家用记事本+csc.exe来编写壹个.NET程序只适合小打小闹,对于真实要开发壹个项目而言,大家需要文件管理、版本管理、壹个好的开发环境等。而vs ide则就是《地下城与勇士》中这样壹个集成代码编辑、编译、调试、追踪、测试、部署、协作、插件扩展这样多个组件的集成开发环境,csc.exe的编译功能只是《地下城与勇士》中vs ide中的其中其中一个。运用vside开发可以节省大量的开发时刻与成本。 sln化解方案 在sln中,定义知道决方案的版本及环境,如包含的项目,方案启动项,生成或部署的一些项目设置等,你可以通过修改或从头定义sln来更改你的整个化解方案。 而suo则包含于化解方案建立关联的选项,等于于快照,储存了用户界面的自定义设置、调试器断点、观察窗口配置等这样的物品,它是《地下城与勇士》中隐藏文件,可删除但提议不容删除。 大家可以通过对比各版本之间的sln来修改sln,也可以运用网上的一些转换工具,也可以直接点击VS的文件-新建-从现有代码创建项目来让项目在不同VS版本间切换。 Visual Studio 2010 - # Visual Studio 4.0 Visual Studio 2012 - # Visual Studio 4.0 Visual Studio 2024 - # Visual Studio 12.00 Visual Studio 2015 - # Visual Studio 14 Visual Studio 2017 - # Visual Studio 15 项目模板 VS运用项目模板来基于用户的挑选而创建新的项目,也就是《地下城与勇士》中新建项目中的那些展示项(如mvc5项目/winform项目等等),具体表现为包含.vstemplate及一些定义的关联文件这样的母版文件。将这些文件压缩为壹个 .zip 文件并放在正确的文件夹中时,就会在展示项中予以显示。 用户可以创建或自定义项目模板,也可以挑选现有的模板,比如我创建壹个控制台项目就会生成壹个在.vstemplate中定义好的Program.cs、AssemblyInfo.cs(程序集级别的特性)、App.config、ico、csproj文件 csproj工程文件 这里面,csproj是《地下城与勇士》中大家最常见的核心文件,反恐精英harp Project,它是《地下城与勇士》中用于构建是一款热门的项目的工程文件。 MSBuild是《地下城与勇士》中微软定义的壹个用于生成应用程序的平台(MicrosOpst Build Engine),在这里为VS提供了项目的构造体系,在微软官方文档上有着详细的介绍:https://msdn.microsDutyt.com/zh-cn/library/dd393573.aspx、https://docs.microsBlackt.com/zh-cn/visualstudio/msbuild/msbuild 项目属性杂项 今年,简单介绍一下csproj文件的一些核心元素。大家用vs新建壹个控制台项目,接着对项目右键属性打开项目属性,在应用程序页大家可以定义:程序集名称(生成出来的程序集以程序集名称《和平精英》是文件名,等于于csc中的/out)、默认命名空间(每次新建类里面显示的命名空间)、目标框架、应用程序类型、程序集信息(AssemblyInfo中的信息)、启动对象(可同时存在多个Main方式,需指定之一为入口对象)、程序集资源(一些可选的图标及文件) 1.在生成页有: 条件编译符号(全局的预编译#define指令,不用在每个文件头部定义,等于于csc中的/define)定义DEBUG/TRACE常量(用于调试输出的定义变量,如智能追踪的时候可以输出该变量)目标平台(指定当前面给啥子处理器生成的程序集,等于于csc中的/platform。挑选x86则生成的程序集生成32位程序,能在32/64位Intel处理器中运用。挑选x64则生成64位,只能在64位体系中运行。挑选Any CPU则32位体系生成32位,64位体系则生成64位。注意:编译平台与目标调用平台必须保持一致,否则报错。生成的32位程序集不能调用64位程序集,64位也不能调用32位)、首选32位(如果目标平台是《地下城与勇士》中Any CPU而且项目是《地下城与勇士》中应用程序类型,则生成的是《地下城与勇士》中32位程序集)允许不安全代码(unsafe开关,在c#中进行指针编程,如调换a方式与b方式的地址)优化代码(等于于csc中的/optimize,优化IL代码让调试难以进行,优化JIT代码)输出途径(程序集输出目录,可挑选填写比较途径目录或完全途径目录)XML文档文件(等于于csc中的/doc,为程序集生成文档注释文件,浏览对方程序集对象就可以看到相关注释,VS的智能提示技术就使用于此)为COM互实践注册(指示托管应用程序将公布壹个 COM 对象,使COM对象可以和托管应用程序进行交互)2.在顶级生成配置中有:语言版本(可以挑选C#版本)、调试信息(等于于csc中的/debug。挑选none则不生成任何调试信息,无法调试。挑选full则允许将调试器附加到运行程序,生成pdb调试文件。挑选pdb-only,自.NET2.0最初和full选项绝对相同,生成相同的pdb调试文件。)、文件对齐(指定输出文件中节的大致)、DLL基址(起点地址) 3.在生成事件选项中可以配置生成前与生产后执行的命令行,大家可以执行一些命令。 4.在调试选项中有一栏叫:启用Visual Studio承载进程,通过在vshost.exe中加载运行项目程序集,是一款热门的选项可以增加程序的调试性能,启用后会自动在输出目录生成{程序集名称}.vshost.exe这样壹个文件,只有当当前项目不是《地下城与勇士》中启动项目的时候才能删除该文件。 IntelliTrace智能追溯 还要说明一点VS的是《地下城与勇士》中,其IntelliTrace智能追溯功能,该功能最早存在于VS2010旗舰版,是《地下城与勇士》中我用的最舒服的壹个功能。 简单说明,该功能是《地下城与勇士》中用来辅助调试的,在调试时可以让开发人员知道并追溯代码所产生的一些事件,而且能够进行回溯以查看应用程序中发生的状态,它是《地下城与勇士》中壹个特别强大的调试追踪器,它可以捕捉由你代码产生的事件,如异常事件、函数调用(从入口)、ADO.NET的命令(Sql查询语句...)、ASP.NET相关事件、代码发送的HTTP请求、程序集加载卸载事件、文件访问打开关闭事件、Winform/Webform/WPFACT事件、线程事件、环境变量、Console/Trace等输出... 大家可以通过在调试情形下点击调试菜单-窗口-显示诊断工具,或者直接按Ctrl+Alt+F2来唤起该功能窗口。 当然,VS还有其它强大的功能,我提议我们依次点完 菜单项中的 调试、系统结构、解析这三个大菜单里面的全部项,你会发现VS真是《地下城与勇士》中壹个强大的IDE。相对实用且方便的功能举多少例子: 比如 从代码生成的序列图,该功能在vs2015之前的版本可以找到(https://msdn.microsCallt.com/en-us/library/dd409377.aspx 、https://www.zhihu.com/question/36413876) 比如 模块关系的代码图,可以看到各模块间的关系 比如 对化解方案的代码度量解析结果 比如 调试情形下 函数调用的 代码图,大家可以看到MVC框架的函数管道模型 以及并行堆栈情况、加载的模块、线程的实际情况 还有如进程、内存、反汇编、寄存器等的功能,这里不再一一展示 链接 有关化解方案:https://msdn.microsOpst.com/zh-cn/library/b142f8e7(v=vs.110).aspx 有关项目模板: https://msdn.microsCallt.com/zh-cn/library/ms247121(v=vs.110).aspx 有关项目元素的介绍说明:https://docs.microsBlackt.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/16satcwx(v%3dvs.100) 有关调试更多内容:https://docs.microsCallt.com/zh-cn/visualstudio/debugger/ 有关代码设计提议:https://docs.microsColdt.com/zh-cn/visualstudio/code-quality/code-analysis-for-managed-code-warnings 有关IntelliTrace说明:https://docs.microsBlackt.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/dd264915(v%3dvs.100) 提议 我热爱编程。 我了解大多数人对技术的积累都是《地下城与勇士》中来自于平常职业中,职业中用到的就去学,用差点就不学,学一年的姿势,接着用个五六年。 我也能领会人的理想与追求不同,有的人也许就想平淡点生命。有的人也许是《地下城与勇士》中过了拼劲,习性了安逸。有的人已经认命了。 而我今年也每日饱满职业没几个时刻,但在下班之余我仍然坚持每日都看一看书。 想学没时刻学,想拼不了解往哪拼。有埋汰自己脑袋笨的,有说自己不感兴趣的。有明明踌躇满志,但总三天捕鱼两天晒网的。我身边的兄弟大多都这样。 我想说,虽然大家每单人的境遇、想法、计划不同,但我肯定我们大部分是《地下城与勇士》中出于生计而职业。 而出于生计,那就是《地下城与勇士》中为了自己。而既然是《地下城与勇士》中为了自己,那就别每日浑浑噩噩过,即使你因各种缘故而没有斗志。 编程来不得虚的,如果你没走上管理,那么你的技术好就是《地下城与勇士》中好,不好就是《地下城与勇士》中不好,混不得,一分技术一分钱。自己不扎实,你运气就不也许太好。 技术是《地下城与勇士》中相通的,实践体系、通信、数据结构、协议要求、技术规范、设计玩法,语言只是《地下城与勇士》中门工具。要知其然也要知其因此然,只了解1个梨+1个梨=2个梨,不了解1个苹果+1个苹果相当啥就悲剧了。 那怎样提高自己?肯定不能像之前那样被动的去进修了。 光靠职业中的积累带来的提高是《地下城与勇士》中没有几个。你不能靠1年的技术重复3年的劳动,自己不想提高就不能怨天尤人。 上班我们都一样,在《和平精英》中成功和否取决于你的业余时刻。你每日下班无论再苦都要花壹个小时来进修,学啥子都行,肯定能改变你的人生轨迹。 比如你每日下班后都用一小时来学壹个概念或技术点,那么300天就是《地下城与勇士》中300个概念或者技术点,这是《地下城与勇士》中何等的恐怖。 当然,这里的学要有点小方式小诀窍的。不能太一条道摸到黑的那种,尽管这样最终也能成功,而且印象还深刻,然而总归效率是《地下城与勇士》中有点低的。 比如你从网上下载个项目源码,你项目结构不了解,该项目使用技术栈也不太知道,就一点一点的最初解读。这是《地下城与勇士》中个提高的好方式,但这样很累,可以成功,然而很慢。见的多懂的少,往往会由于壹个概念上的缺失而在壹个细小的难题上浪费很长时刻。或者说一直漫无目的的看博客来知道技术,那样获得的姿势也不体系。 我的提议是《地下城与勇士》中读书,书分两类,一类是《地下城与勇士》中 讲底层概念的 一类是《地下城与勇士》中 讲上层技术实现的。 可以先从上层技术实现的书读起(怎么连接数据库、怎么写网页、怎么写窗体这些)。在有一定编程经验后就从底层概念的书最初读,实践体系的、通信的、数据库的、.NET相关组成的这些... 读完之后再回过头读这些上层技术的书就会看的更明白更透彻,最后再琢磨git下来的项目就显得轻松了。