Sna*_*ake 12 .net c# language-design using-statement c#-2.0
我正在尝试阅读我编译的C#代码.
这是我的代码:
using(OleDbCommand insertCommand = new OleDbCommand("...", connection))
{
// do super stuff
}
Run Code Online (Sandbox Code Playgroud)
但!
我们都知道使用被转换为:
{
OleDbCommand insertCommand = new OleDbCommand("...", connection)
try
{
//do super stuff
}
finally
{
if(insertCommand != null)
((IDisposable)insertCommand).Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
(因为OleDbCommand是一个引用类型).
但是当我反编译我的程序集(用.NET 2.0编译)时,我在Resharper中得到了这个:
try
{
insertCommand = new OleDbCommand("", connection);
Label_0017:
try
{
//do super stuff
}
finally
{
Label_0111:
if ((insertCommand == null) != null)
{
goto Label_0122;
}
insertCommand.Dispose();
Label_0122:;
}
Run Code Online (Sandbox Code Playgroud)
我在说这句话:if ((insertCommand == null) != null)
.
假设insertCommand为null.然后第一部分返回true.(true != null)
回报true
.那么处置仍然被跳过?奇怪,非常奇怪.
如果我在Visual Studio中粘贴它,Resharper已经警告过我:表达总是如此......
谢谢!
-Kristof
Eri*_*ert 12
反编译器有一个bug.这条线
if ((insertCommand == null) != null)
Run Code Online (Sandbox Code Playgroud)
应该被反编译成
if ((insertCommand == null) != false)
Run Code Online (Sandbox Code Playgroud)
虽然不必要地冗长,但至少是正确的代码.
反编译器可能会做这个不必要的冗长版本,因为C#编译器经常选择发出
if (x)
Y();
Z();
Run Code Online (Sandbox Code Playgroud)
好像你写的那样
if (!x)
goto L;
Y();
L: Z();
Run Code Online (Sandbox Code Playgroud)
由于为两个程序生成的代码是相同的,因此反编译器并不总是知道哪一个是要显示的更合理的代码.
意外的"!= false"的原因是因为当我们生成测试某些内容是否为真的IL时,我们可以生成的最快和最紧凑的代码是测试它是否为假.在IL中,False表示为零,并且有一个便宜的指令"这个零是什么?"
归档时间: |
|
查看次数: |
663 次 |
最近记录: |