在没有语法糖的情况下将IL转换为C# [英] Converting IL to C# with no syntactic sugar

查看:188
本文介绍了在没有语法糖的情况下将IL转换为C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个程序,该程序将向我显示给出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) da; 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆