.net - 如果 CIL 仅基于堆栈,为什么它支持实例

标签 .net oop static instance cil

在通用中间语言 (CIL) 中,我们可以实例化非静态的类。如果我们需要在方法调用之间存储实例数据,那将非常有意义。为什么在一切都位于堆栈上的 CIL 中这是必要的? CIL中没有存储实例数据,为什么需要实例?或者责怪编译器:为什么编译器不将 CIL 中的每个方法都编译为静态的?我最好的猜测是可以从 CIL 中提取更高级别代码的信息。这对于有经验的 CIL 程序员来说可能听起来很愚蠢,因为它可能是完全错误的,但我才刚刚开始接触它。

非常感谢任何澄清。

最佳答案

CIL 中的隐含假设是类对象存储在 GC 堆上。在运行时也准确。创建对象时返回的是对该对象的引用。一个指针。 32位模式占用4字节,64位模式占用8字节。

您对该指针的操作取决于您的代码。您可以将其存储在局部变量中(类似于将其存储在堆栈中),也可以将其存储在字段或静态变量中。在运行时,它与 IntPtr 没有根本区别,只是垃圾收集器总能找到它。当它压缩堆时移动对象是必要的,指针值需要更新。引擎盖下发生了很多魔法来帮助 GC 找到那个指针,即时编译器 plays an essential role .

从运行时的角度来看,所有的方法都是静态的。编写扩展方法时非常明显。 C# 静态方法和实例方法之间的区别在于传递给方法的额外隐藏参数。你很清楚,就是这个。您始终可以在实例方法中使用的关键字。您不必在方法的参数列表中自己命名它,编译器会处理它。您确实在扩展方法中明确命名了它。

关于.net - 如果 CIL 仅基于堆栈,为什么它支持实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40036613/

相关文章:

c# - 为什么我不能在 PostBack 上更新 HiddenFields?

javascript - 如果我可以随时向对象插入任何属性,那么在 javascript 中创建类有什么用

java - 为什么在 Java 中不重写静态方法?

java - 在 Java 中从构造函数调用的静态方法

c# - 将指数数转换为整数

c# - 当未进行 4 字节对齐时,Monotouch 浮点指针会抛出 NullReferenceException

c# - 如何按两个属性对这个简单的 .NET 列表进行排序?

oop - 使用 oop 继承的 angularjs

javascript - 稍后在不使用 .prototype 的情况下将其他功能添加到类中

java - 在 Java 中通过对象引用访问静态变量