当我主要做 c++ 时,我认为了解汇编和编写一些非试用 asm 代码很重要,这样我才能真正理解发生了什么。我现在主要做.net,虽然我对 IL 有一些了解,但我并不精通。
IL 是一种应该具备的技能,还是会更完整地学习 IL 以了解我如何使用和编写 .net 代码?
在很多方面,完全学习 IL 就像学习汇编。
了解 IL 可以帮助您了解实际编译 .NET 代码时会发生什么。这可能非常有帮助,尤其是当您遇到性能关键的分析情况时(您发现了一个真正的问题,并且需要对其进行优化)。
但是,对于大多数“日常”编程任务,我认为没有必要了解 IL,就像大多数 C++ 程序员不需要知道如何编写汇编一样。
话虽如此,如果您了解具有 C++ 背景的汇编代码,那么对 IL 有一个大致的了解将非常非常容易......
如果您只是想编写一个 .NET 应用程序,则不需要任何 IL 代码的工作知识。大多数 .NET 开发人员不知道如何编写 IL 代码。
如果您试图了解真正发生的事情,IL 将帮助您。您可以使用它在机器上编写更高效的代码,这在您正在编写的 .NET 语言中可能并不明显。
除了显而易见的(实现虚拟机)之外,某些类型的任务需要对 IL 有相当透彻的了解。
我个人最感兴趣的方面之一是检查 IL 语言对即时编译器的影响。对比 JVM 和 CLI 的一个显着示例是 CLI 具有非虚拟方法和直接分派的概念,它允许非优化(基线)编译器发出特别有效的调用。这种分析在 JVM 中成本更高,因此基线编译器无法优化尽可能多的情况。
一般来说,.NET 开发人员不必担心学习 CIL。如果您的工作涉及运行时/动态生成的方法,那么您应该评估 Expressions API 满足您需求的能力,因为它非常有用/可维护。我花了几个星期用 ILGenerator 发出 CIL。我花了一个时间来转换为 Expressions,节省了一百多行代码并修复了我还没弄清楚的旧错误。
CIL 的详细知识对于任何实现 CLI 虚拟机或编写编译器(AOT 或 JIT)的人来说都非常重要。我觉得它既有趣又有用,但在“成为一名高效开发人员需要了解的重要事项”的范围内,它并没有那么高。
在 .NET 框架中实际上只有一个地方需要了解 IL,即 System.Reflection.Emit 命名空间中的类。它使您可以动态生成代码,这在某些情况下很有用。
接触 IL 的最好方法是通过 Ildasm.exe 工具,Reflector 也可以工作。运行它的一种非常方便的方法是将其添加到“工具”菜单中。工具 + 外部工具,添加。
您现在可以编写一些托管代码、编译并快速查看生成的 IL。如果您以前接触过机器代码,您会发现它很容易上手。请记住,IL 是无类型的,相同的操作码可用于任何值类型。
下一步是看看 IL 是如何被翻译成机器代码的。开始调试,右键单击代码并选择 Go To Disassembly。请注意,除非您运行 Release 构建并启用 JIT 优化,否则您不会查看真实的机器代码。工具 + 选项,调试,取消勾选“在模块加载时抑制 JIT 优化”。
了解汇编对于 Visual Studio 中的 C/C++ 非常有用。你总是可以去拆卸看看发生了什么。
如果您在 C# 中尝试相同的操作,即“转到反汇编”,您仍然会使用本机代码,而不是 IL。从这个意义上说,IL 不如真正的汇编有用。
但是 IL 非常适合查看您也没有源代码的程序集。(但你可以使用反射器)
要看。了解 IL 可能会帮助您了解您的代码变成了什么。如果您对 IL 有很好的了解,您甚至可以在运行时创建新组件(如果需要)。是必不可少的吗?可能不是。
不,就像大多数人所说的那样。另外,要添加到他们的评论中,请查看为什么使用 C/C++ 以及为什么使用 .NET 及其语言(如 C#):
C/C++ 旨在以一种很好的抽象方式为您提供对计算机的控制权。它几乎可以直接转换成汇编语言,并为您提供强大的善(恶)力。鼓励使用指针之类的东西,并且没有垃圾收集。因此,您必须知道汇编语言代码在做什么,因为您可以做什么。
.NET 语言旨在快速制作出色的应用程序并限制您对这些应用程序造成的损害。它不鼓励你在 CPU 上使用真正的权力(就像不鼓励使用指针一样,你不必担心大部分垃圾收集。)基本上,你可以做的损害仅限于应用程序;并且与 CPU 几乎没有关系(除非你涉足不安全的代码,它只在极少数情况下使用 [根据我的经验])。此外,.NET 代码被转换为 IL,然后 IL 被转换为程序集等等......无论如何,您并不是直接处理汇编语言。
说了这么多,了解IL头部知识很好,可以帮到你一点。但是知道它不会极大地帮助您创建出色的应用程序 - 这是 .NET 语言对于大多数不在 Microsoft 工作的开发人员的重点。