cil

[C#]浅析ref、out参数

ε祈祈猫儿з 提交于 2020-08-10 14:29:48
按引用传递的参数算是C#与很多其他语言相比的一大特色,想要深入理解这一概念应该说不是一件容易的事,再把值类型和引用类型给参杂进来的话就变得更加让人头晕了。 经常看到有人把按引用传递和引用类型混为一谈,让我有点不吐不快。再加上前两天碰到的一个有意思的问题,让我更加觉得应该整理整理关于ref和out的内容了。 一、 什么是按引用传递 ref和out用起来还是非常简单的,就是在普通的按值传递的参数前加个ref或者out就行,方法定义和调用的时候都得加。 ref和out都是表示按引用传递,CLR也完全不区分ref还是out,所以下文就直接以ref为例来进行说明。 大家都知道,按值传递的参数在方法内部不管怎么改变,方法外的变量都不会受到影响,这从学C语言时候就听老师说过的了。 在C语言里想要写一个Swap方法该怎么做?用指针咯。 那么在C#里该怎么做?虽然也可以用指针,但是更通常也更安全的做法就是用ref咯。 说到这里,有一点需要明确,按值传递的参数到底会不会被改变。 如果传的是int参数,方法外的变量肯定是完完全全不变的咯,可是如果传的是个List呢?方法内部对这个List的所有增删改都会反映到方法外头,方法外查一下Count就能看出来了是吧。 那么传List的这个情况,也代表了所有引用类型参数的情况,方法外的变量到底变没变? 不要听信某些论调说什么“引用类型就是传引用”

还不明白可空类型原理? 我可要挖到底了

对着背影说爱祢 提交于 2020-07-28 18:57:49
一:背景 1. 讲故事 下决心做好自媒体到现在有一个月了,关注我的兄弟应该知道我产出了不少文章,号里的粉丝也多起来了,我也尽最大努力做到有问必回,现在是基础的、高深的问题都接踵而来,可我也只是一只小菜鸟,想飞也飞不动了(┬_┬),昨天号里有位朋友被面试官问到可空类型的原理,回答的不好,面试官也是,面就面呗,又给不了多少银子,还动不动就原理,哪有那么多原理,搞得双方都尴尬😄😄😄。 二:给我锄头我要挖到底 这种问题要怎么挖呢? 我在之前的文章也聊过,C#代码到机器码中间有两个编译过程,一个是csc编译后的IL代码,一个是jit编译后的native代码,所以搞懂IL代码和native代码就是我们要深究的方向,我还是把那篇文章的图拿过来。 为了方便演示,我就定义一个 int? 类型,接收非null和null两种情况。 static void Main(string[] args) { int? num1 = 10; int? num2 = null; Console.WriteLine("执行结束啦!"); Console.ReadLine(); } 1. 挖IL代码 挖IL代码简单,用ILSPY小工具就可以了,编译后生成的IL代码如下: .method private hidebysig static void Main ( string[] args ) cil managed { /

Difference between the “ceq” MSIL command and object.InternalEquals

匆匆过客 提交于 2020-06-25 05:11:24
问题 I was digging around in ILDASM and Reflector as found that: == is compiled to the "ceq" MSIL command object.Equals is left as is object.Equals calls object.InternalEquals This question showed me how to find out how InternalEquals might be implemented i.e. in .cpp class (or whatever, somewhere in the CLR). My question is: What does ceq become? Another method in a different .cpp class? I.e. they are completely different peices of code? So although the default behaviour of == and Equals appears

Difference between the “ceq” MSIL command and object.InternalEquals

十年热恋 提交于 2020-06-25 05:11:20
问题 I was digging around in ILDASM and Reflector as found that: == is compiled to the "ceq" MSIL command object.Equals is left as is object.Equals calls object.InternalEquals This question showed me how to find out how InternalEquals might be implemented i.e. in .cpp class (or whatever, somewhere in the CLR). My question is: What does ceq become? Another method in a different .cpp class? I.e. they are completely different peices of code? So although the default behaviour of == and Equals appears

What's the difference between sizeof(T) and Unsafe.SizeOf<T>()?

 ̄綄美尐妖づ 提交于 2020-05-10 06:55:26
问题 First of all, a small disclaimer before the actual question: I know there are a lot of closed/duplicate questions regarding the difference between the sizeof operator and the Marshal.SizeOf<T> method, and I do understand the difference between the two. Here I'm talking about the SizeOf<T> method in the new Unsafe class So, I'm not sure I understand the actual difference between these two operations, and whether there's a specific difference when using the method on a struct/class in

C#接口与抽象类学习笔记

我与影子孤独终老i 提交于 2020-04-26 13:51:21
本笔记摘抄自: https://www.cnblogs.com/solan/archive/2012/08/01/CSharp06.html ,记录一下学习过程以备后续查用。 摘要: 抽象类:是一种特殊的类,可以定义具有实现的方法,也可以定义未实现的方法契约,本身不能被实例化,只能在派生类中进行实例化。接口:对一 组方法签名进行统一的命名,只能定义未实现的方法契约,本身也不能被实例化,只能在实现类中进行实例化。 二者都可以有部分数据成员(如:属性),它们貌似有着相同的“契约”功能,但对各自的派生类(实现类)又有着不同的要求,那么,到底它们有何 异同呢?下面将从四个方面来讲解它们的相同与不同之处。 一、定义 抽象类 不能实例化。抽象类的用途是提供多个派生类可共享的基类的公共定义,是对类进行抽象,可以有实现,也可以不实现。使用关键字abstract 进行定义。 下面定义一个抽象类: public abstract class Code_06_03 { } 通过ISDASM来看一下生成的IL: . class abstract auto ansi nested public beforefieldinit Code_06_03 extends [mscorlib]System.Object { } // end of class Code_06_03 可以看以

C#接口与抽象类学习笔记

时光怂恿深爱的人放手 提交于 2020-04-26 11:35:42
本笔记摘抄自: https://www.cnblogs.com/solan/archive/2012/08/01/CSharp06.html ,记录一下学习过程以备后续查用。 摘要: 抽象类:是一种特殊的类,可以定义具有实现的方法,也可以定义未实现的方法契约,本身不能被实例化,只能在派生类中进行实例化。接口:对一 组方法签名进行统一的命名,只能定义未实现的方法契约,本身也不能被实例化,只能在实现类中进行实例化。 二者都可以有部分数据成员(如:属性),它们貌似有着相同的“契约”功能,但对各自的派生类(实现类)又有着不同的要求,那么,到底它们有何 异同呢?下面将从四个方面来讲解它们的相同与不同之处。 一、定义 抽象类 不能实例化。抽象类的用途是提供多个派生类可共享的基类的公共定义,是对类进行抽象,可以有实现,也可以不实现。使用关键字abstract 进行定义。 下面定义一个抽象类: public abstract class Code_06_03 { } 通过ISDASM来看一下生成的IL: . class abstract auto ansi nested public beforefieldinit Code_06_03 extends [mscorlib]System.Object { } // end of class Code_06_03 可以看以

.NET Framework简介

℡╲_俬逩灬. 提交于 2020-04-21 05:54:54
一、CLR集成了很多种语言,他们之间可以互相访问,是因为CLR建立的标准的类型集、元数据、公共执行环境。   由于各种语言间存在着极大的差别,如区分大小写,有的不支持unsigned、操作符重载或者参数可变方法,   所以想要创建这种让别的语言能访问的程序,自己所用的编程语言只能使用其它语言都支持的那些特性。   为了帮助我们更好的做到这一点,Microsoft定义一个“公共语言规范(Common Language Specification,CLS)”。 二、CTS定义了一组语言编译器必须遵循的规则,以定义、引用、使用和存储引用类型和值类型。因此,遵循CTS,   在不同语言中编写的对象才能彼此交互。但并不是所有的类型都可以用于所有的语言。 三、Language Complile:语言编译器,每种语言基于.net的语言都会有一个面向CLR的托管模块,也可以理解为语言   编译器,把对应的语言编译成MSIL。   MSIL:微软中间语言,CLR负责把中间语言编译成为执行程序的计算机可以理解的语言,是一种介于高级语言和      汇编语言的伪汇编语言。   JIT(Just In-Time Compile):即时编译,将MSIL解释为程序可以理解的语言。 四、CLR的执行模型   1、将源代码(vb、cs)编译成托管代码块。托管代码块有中间语言和元数据组成。   2

直接使用汇编编写 .NET Standard 库

时间秒杀一切 提交于 2020-04-17 16:45:40
前言 Common Language Runtime(CLR)是一个很强大的运行时,它接收 Common Intermediate Language(CIL) 的输入并最终产生机器代码并执行。CIL 在 CLR 上相当于 ASM 汇编代码的存在。 CLR 之上的语言 C#、F#、VB.NET 等语言的类型系统固然设计得不错,但是有的时候我们需要一些操作绕过类型系统的检查,或者有的时候语言本身并不能满足我们的需求。 需要使用 CIL 的常见场景: 我们需要绕过类型系统,在类型系统上面 “开洞”。 我们需要优化程序的性能,直接使用 CIL 编程可以如同使用汇编一样完全的控制程序的逻辑,对程序进行人肉优化。 直接利用 C#、F# 等语言编译成的 CIL 有其独特的模式,容易被反编译软件从 CIL 还原为源代码,而如果直接采用 CIL 编程则很容易避开编译器生成代码的固有模式,使得代码无需进行任何混淆即可让所有反编译器失效。 需要注意:CLR 的 JIT 部分优化依赖于 CIL 的特定模式,直接采用 CIL 进行编程而不利用 C# 等语言的编译器生成特定模式的 CIL 可能导致优化失效,如向量化、模式匹配缓存和常数时间优化等,因此在直接使用 CIL 进行编程时最好对 CLR 的 JIT 有一定了解,以规避潜在的性能问题,JIT 的源代码在 https://github.com/dotnet

直接使用汇编编写 .NET Standard 库

不羁岁月 提交于 2020-04-17 15:16:05
【推荐阅读】微服务还能火多久?>>> 前言 Common Language Runtime(CLR)是一个很强大的运行时,它接收 Common Intermediate Language(CIL) 的输入并最终产生机器代码并执行。CIL 在 CLR 上相当于 ASM 汇编代码的存在。 CLR 之上的语言 C#、F#、VB.NET 等语言的类型系统固然设计得不错,但是有的时候我们需要一些操作绕过类型系统的检查,或者有的时候语言本身并不能满足我们的需求。 需要使用 CIL 的常见场景: 我们需要绕过类型系统,在类型系统上面 “开洞”。 我们需要优化程序的性能,直接使用 CIL 编程可以如同使用汇编一样完全的控制程序的逻辑,对程序进行人肉优化。 直接利用 C#、F# 等语言编译成的 CIL 有其独特的模式,容易被反编译软件从 CIL 还原为源代码,而如果直接采用 CIL 编程则很容易避开编译器生成代码的固有模式,使得代码无需进行任何混淆即可让所有反编译器失效。 需要注意:CLR 的 JIT 部分优化依赖于 CIL 的特定模式,直接采用 CIL 进行编程而不利用 C# 等语言的编译器生成特定模式的 CIL 可能导致优化失效,如向量化、模式匹配缓存和常数时间优化等,因此在直接使用 CIL 进行编程时最好对 CLR 的 JIT 有一定了解,以规避潜在的性能问题,JIT 的源代码在 https: