是否管理C#不安全代码?

Bac*_*ave 0 c# clr managed

如果您编写了C#程序,并且部分代码是使用unsafe关键字编写的,那么该代码是否仍被视为“托管”代码?

即。它会在CLR下运行吗?

gia*_*min 5

托管代码(来自 MSDN):

托管代码是用二十多种可与 Microsoft .NET Framework 一起使用的高级编程语言之一编写的代码,包括 C#、J#、Microsoft Visual Basic .NET、Microsoft JScript .NET 和 C++。所有这些语言共享一组统一的类库,并且可以编码为中间语言(IL)。运行时感知编译器将 IL 编译为托管执行环境中的本机可执行代码,确保类型安全、数组绑定和索引检查、异常处理和垃圾收集。通过使用托管代码并在此托管执行环境中进行编译,您可以避免许多导致安全漏洞和不稳定应用程序的典型编程错误。此外,许多非生产性的编程任务也会自动处理,例如类型安全检查、内存管理和不需要的对象的销毁。

托管代码在 CLR 的监督下运行,CLR 负责内存管理和垃圾收集。

否则,非托管代码将在 CLR 上下文之外运行。

不安全代码仍然在 CLR 下运行,并被翻译为 IL,但它会让您直接通过指针访问内存。


Han*_*ant 5

“托管代码”不能帮助您unsafe正确考虑关键字。关于托管代码的最基本方面是它与垃圾回收器兼容。它必须能够找到该代码使用的对象引用,以便可以正确确定该对象是否在使用中。这需要一个非常具体的细节,运行时GC必须能够找到一张表,该表描述了对象引用的存储位置。局部变量和方法参数是棘手的。该表是由即时编译器或Ngen.exe或.NET Native这样的提前编译器生成的。

C#始终生成托管代码,没有选项来生成GC无法探测的方法。可以在.NET程序集中生成非托管代码,C ++ / CLI编译器可以做到这一点。暗示C#代码始终需要CLR,没有它就没有GC。

unsafe代码的高度特定之处在于它是不可验证的。它使用即时编译器无法检查的MSIL指令来确保它不会破坏内存。指针是最明显的情况,抖动无法知道指针取消引用是否安全,它尚不知道指针值。

无法验证的代码的结果是,有人可以将您的程序集加载到沙箱中,并坚持要求所有代码都必须是可验证的。它不会工作。当然,最终的结果是,您弄乱了代码并写入内存中的任意地址,从而产生了非常难以诊断的错误。损失了一周的生命才发现该错误是可以预期的。