在没有语法糖的情况下将IL转换为C# [英] Converting IL to C# with no syntactic sugar
问题描述
我正在寻找一个程序,该程序将向我显示给出IL代码的最低级别的C#代码(即没有语法糖).
I'm looking for a program that will show me the lowest level (ie. no syntactic sugar) C# code given IL code.
我尝试使用.NET Reflector查看一个.exe文件,该文件包含带有foreach
循环的简单控制台应用程序,希望看到GetEnumerator()
,MoveNext()
,Current
等,但是它显示为foreach
循环.
I tried using .NET Reflector to view a .exe file that contained a simple console app with a foreach
loop, hoping to see GetEnumerator()
, MoveNext()
, Current
etc, however it showed it as a foreach
loop.
是否存在这样的程序?还是可以在.NET Reflector中选择无语法糖"?
Does such a program exist? Or is it possible to select "no syntactic sugar" in .NET Reflector?
推荐答案
ILSpy 的当前版本有一组用于启用/禁用反编译器转换功能的选项:
Current versions of ILSpy have a sizable set of options for enabling/disabling decompiler transformation features:
...
static void Main(string[] args) {
foreach (var arg in args) {
Console.WriteLine(arg);
}
}
...
如果需要,您可以通过剥离ICSharpCode.Decompiler.IL.Transforms.*
和ICSharpCode.Decompiler.CSharp.StatementBuilder
中的逻辑来做进一步的工作.也许打开一个问题,询问您对更改所做的PR是否会受到赞赏,因为大多数这些原始性"设置是在最近才添加的.
If needed, you could go further than this by stripping out logic in ICSharpCode.Decompiler.IL.Transforms.*
and ICSharpCode.Decompiler.CSharp.StatementBuilder
; Perhaps open an issue asking, whether a PR for your changes would be appreciated, as most of these "rawness" settings have been added relatively recently.
简洁的代码段
var numbers = new List<int> { 0, 1, 2 };
foreach (var num in numbers) Console.WriteLine(num);
编译为
System.Collections.Generic.List<int> list = new System.Collections.Generic.List<int>();
list.Add(0);
list.Add(1);
list.Add(2);
System.Collections.Generic.List<int> numbers = list;
System.Collections.Generic.List<int>.Enumerator enumerator = numbers.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
int num = enumerator.Current;
System.Console.WriteLine(num);
}
}
finally
{
((System.IDisposable)enumerator).Dispose();
}
(在禁用所有转换设置的情况下可见)
(as seen with all transformation settings disabled)
就编译而言,for (a; b; c) d
与a; while (b) { d; c; }
相同(保留continue-label的位置),因此反编译器将根据init之间的上下文相似性自由决定它可能是哪种循环语句,条件和后语句,因此您甚至可以手动编写代码
As far as compilation goes, for (a; b; c) d
is the same as a; while (b) { d; c; }
(save for placement of continue-label), so decompilers will take liberty with deciding what kind of loop it might have been based on context similarity between init-statement, condition, and post-statement, so you might even write code by hand
var a = 0;
while (a < args.Length) {
Console.WriteLine(args[a]);
a++;
}
将被检测为for循环(因为IL中没有告诉)
that will be detected as a for-loop (for there is no telling in IL)
for (int a = 0; a < args.Length; a++)
{
System.Console.WriteLine(args[a]);
}
这篇关于在没有语法糖的情况下将IL转换为C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!