【问题标题】:'using' block compiler generated code not visible in dotPeek or ILSpy“使用”块编译器生成的代码在 dotPeek 或 ILSpy 中不可见
【发布时间】:2015-10-28 13:01:05
【问题描述】:

我有兴趣查看生成try-finallyusing 代码块的编译器生成代码,但我没有看到dotPeekILSpy 都显示了这个细节。我用ildasm.exe 来查看这个代码块,我发现它里面有try-finally 块,但不能很好地理解它......所以想看看这两个工具是否有帮助。

有什么想法吗?

更新: 所以我最近在我的项目中使用了一个实现 IDisposable 的结构,并担心 using 代码块和带有 IDisposable 的结构会导致装箱......但后来我发现下面的文章提到编译器针对这种情况进行了优化并且确实尝试调用 Dispose 时不框。

http://ericlippert.com/2011/03/14/to-box-or-not-to-box/

所以我很想知道编译器会为我的 using 块生成什么样的代码。

一个简单的例子repro:

【问题讨论】:

  • 贴一些示例反编译代码!
  • ILSpy(我猜也是 dotPeek)将识别编译器生成的 using 语句扩展并将其反转回 using 语句。
  • 如果您想了解 IL,请参阅 here。一条 MSIL 指令将沿着 .try L_000b to L_001d finally handler L_001d to L_0027 的行生成,以及一条类似 leave.s L_0027 的指令。
  • 更新了更多信息。
  • 在 ILSpy 中选择 IL 作为语言,然后它将显示原始 IL,因此没有任何内容被隐藏。

标签: c# ilspy dotpeek


【解决方案1】:

免费JustDecompile tool from Telerik可以显示详情。

基本上(Test 是实现IDisposable 的示例类),编译版本:

internal class Program
{
    private static void Main(string[] args)
    {
        using (var test = new Test())
        {
            test.Foo();
        }

        Console.ReadLine();
    }
}

反编译为:

internal class Program
{
    public Program()
    {
    }

    private static void Main(string[] args)
    {
        Test test = new Test();
        try
        {
            test.Foo();
        }
        finally
        {
            if (test != null)
            {
                ((IDisposable)test).Dispose();
            }
        }
        Console.ReadLine();
    }
}

【讨论】:

  • test 转换为 IDisposable 的任何原因?一个人可以直接调用test.Dispose() 而不用强制转换。
  • @MatiasCicero 请参阅“备注”msdn.microsoft.com/en-us/library/yh598w02.aspx
  • @MatiasCicero 我假设编译器会这样做,所以生成的代码对于IDisposable的隐式和显式实现都是相同的
  • @MatiasCicero 它是强制转换的,以防它使用显式实现来实现。
  • @MatiasCicero:Test 可能shadow Dispose。在这种情况下,test.Dispose()((IDisposable)test).Dispose() 的行为会有所不同。
猜你喜欢
  • 1970-01-01
  • 2013-04-01
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多