Lau*_*ant 13 .net c# cil decompiler
给出以下C#代码,其中以两种不同的方式调用Dispose方法:
class Disposable : IDisposable
{
public void Dispose()
{
}
}
class Program
{
static void Main(string[] args)
{
using (var disposable1 = new Disposable())
{
Console.WriteLine("using");
}
var disposable2 = new Disposable();
try
{
Console.WriteLine("try");
}
finally
{
if (disposable2 != null)
((IDisposable)disposable2).Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
一旦使用发布配置编译然后用ildasm反汇编,MSIL看起来像这样:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 57 (0x39)
.maxstack 1
.locals init ([0] class ConsoleApplication9.Disposable disposable2,
[1] class ConsoleApplication9.Disposable disposable1)
IL_0000: newobj instance void ConsoleApplication9.Disposable::.ctor()
IL_0005: stloc.1
.try
{
IL_0006: ldstr "using"
IL_000b: call void [mscorlib]System.Console::WriteLine(string)
IL_0010: leave.s IL_001c
} // end .try
finally
{
IL_0012: ldloc.1
IL_0013: brfalse.s IL_001b
IL_0015: ldloc.1
IL_0016: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_001b: endfinally
} // end handler
IL_001c: newobj instance void ConsoleApplication9.Disposable::.ctor()
IL_0021: stloc.0
.try
{
IL_0022: ldstr "try"
IL_0027: call void [mscorlib]System.Console::WriteLine(string)
IL_002c: leave.s IL_0038
} // end .try
finally
{
IL_002e: ldloc.0
IL_002f: brfalse.s IL_0037
IL_0031: ldloc.0
IL_0032: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0037: endfinally
} // end handler
IL_0038: ret
} // end of method Program::Main
Run Code Online (Sandbox Code Playgroud)
像DotPeek或JustDecompile这样的.NET反编译器如何区分使用和尝试...最终?
它实际上没有什么区别.正如Mark在评论中所说 - 如果你编写的代码与编译器生成的相同using- 反编译器将无法发挥作用.
但是,许多反编译器,包括DotPeek,实际上可以使用调试符号(.pdb)文件来定位实际的源代码,然后使用实际的源代码,这样就不会发生任何反编译.此外,在调试模式下进行编译也可能会影响模式(即 - 您尝试模仿using语句可能在调试与发布编译中产生不同的结果IL).
要防止DotPeek使用您的真实源代码文件,请转到"工具">"选项">"反编译器",然后取消选中"使用符号文件中的源"(如果可用).然后在Release中编译你的代码并观察DotPeek将两个语句反编译为using.