反编译汇编代码为什么看起来不完全像用于编译的C#代码?

6

我丢失了包含我的代码的原始项目,但是我仍然有汇编代码,所以我决定使用DotPeek进行反编译。从中得到的以下代码引起了我的注意:

int num1 = 1;
saveFileDialog1.OverwritePrompt = num1 != 0;

为什么要使用那个复杂的代码而不是这个简单的代码?
saveFileDialog1.OverwritePrompt = true;

3
C# 编译器不必进行任何优化 - 在许多情况下也没有。它只是将代码翻译成 CLR 的 IL。然后即时编译器在将代码编译成本地机器语言时进行优化。 - davidbak
7
这是反编译的副产品,不能视为C#的规则。 - Steve
以上的回答解决了我的问题。谢谢,案件关闭。 - HyunMi
你好,能否提供这一部分的IL代码给我们呢?我对这个案例很感兴趣。 - whymatter
如果您认为任何评论是答案,请将其复制为答案并接受它。 - Lex Li
1个回答

5

您在此展示的只是使用 dotPeek 反编译程序集中 MSIL 代码回到 C# 时的一个副产品。C# 中的某些语言结构在编译时会被重写成完全不同的东西,通常涉及到 goto 语句(例如 foreach 循环和 LINQ 语句)。如果反编译程序只是直接将 MSIL 翻译成 C#,则生成的 C# 代码经常会难以识别。因此,任何像样的或者非平凡的反编译程序都将识别这些结构,并且不提供字面翻译,而是会用 foreach 循环或 LINQ 等等来替换使用 goto 的循环,以便生成更接近产生该 IL 的原始 C# 代码。

这可不是一件容易的事情!必须考虑到的情况非常多,而且随着 Microsoft 向框架添加新类,这种情况还会不断增加。考虑到这些因素,它们能够胜任的程度相当令人印象深刻。您在这方面所得到的效果取决于不同的反编译程序,不同的反编译程序在给定相同的 IL 时会生成不同的 C# 代码。然而(从理论上讲),它们都应该生成功能相同的代码。

我所见过的最好的(免费)反编译器是 ILSpy(可在 ILSpy.net 上下载),远胜其他工具。这个工具是开源的,作者(我猜测)是写了一个开源 IDE SharpDevelop 的人,该 IDE 是 Visual Studio 的替代品。ILSpy 可以将 MSIL 反向转换为我们熟悉的原始 C# 构造,包括大多数 LINQ 语句。考虑到这个开发工作只由一个人完成,ILSpy 处理的案例数量令人惊叹。ILSpy 还可以从 MSIL 转换为 VB .NET,但我认为大部分从生成的 IL 代码翻译回产生这样的 IL 代码的原始 VB .NET 代码结构的神奇翻译尚未实现。我只见过一次 ILSpy 做错事情(非常深层嵌套的 if 语句导致疯狂的箭头代码,我说的是数百个 if 语句深度),我不知道产生这样一团糟的原始 C# 代码是什么(它是来自我反编译的游戏 Terraria 的一些数学/绘图代码)。

您可以阅读他的博客,了解他如何实现ILSpy的一些功能。

我鼓励您尝试ILSpy,看看它是否能为您生成更明智的代码。即使这样,您几乎肯定会发现一些想要修改或重写的代码,以便您满意。在可怕的Visual Studio错误吞噬原始代码之后,我不得不反编译一个模块,这种情况本可以通过更频繁地检查我的代码来避免。我确实记得需要仔细清理代码,删除冗余内容,并对我认为最有意义的代码进行更改。此外,您可能会发现您喜欢不同的反编译器处理不同代码部分的方式,并可能最终使用不同调试器输出的混合版本来实现您满意的代码版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接