A confusing fact about using statement

转载 2006年05月25日 12:42:00

A confusing fact about using statement

Using语句提供简洁的语法来保证资源的回收,然而并不是所有的人都懂得using语句的实现。
在写篇Blog之前,我在Google上Search一下,发现了如下的文章:
http://www.codeproject.com/csharp/TinguUsingStatement.asp
不幸的是这片文章中有一个严重的错误。
在往下读之前,请先看看下面的Code有什么问题:

RegistryKey typeNameKey = null;
 using (typeNameKey) {
  typeNameKey = Registry.ClassesRoot.CreateSubKey(".ABCD");
  typeNameKey.SetValue("", "Test");
 }
// continue to do some work

如果执行这段代码,你会发现在Using Block结束后RegistryKey没有被回收(Dispose)
为什么? 让我们看看IL Code:

  IL_0000:  ldnull
  IL_0001:  stloc.0
  IL_0002:  ldloc.0
  IL_0003:  stloc.1
  .try
  {
    IL_0004:  ldsfld     class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.Registry::ClassesRoot
    IL_0009:  ldstr      ".ABCD"
    IL_000e:  callvirt   instance class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.RegistryKey::CreateSubKey(string)
    IL_0013:  stloc.0
    IL_0014:  ldloc.0
    IL_0015:  ldstr      ""
    IL_001a:  ldstr      "Test"
    IL_001f:  callvirt   instance void [mscorlib]Microsoft.Win32.RegistryKey:SetValue(string,
                                                                                       object)
    IL_0024:  leave.s    IL_0030
  }  // end .try
  finally
  {
    IL_0026:  ldloc.1
    IL_0027:  brfalse.s  IL_002f
    IL_0029:  ldloc.1
    IL_002a:  callvirt   instance void [mscorlib]System.IDisposable:Dispose()
    IL_002f:  endfinally
  }  // end handler

注意黑体部分,在finally block中回收的是using block中的代码执行前typeNameKey的值。
如果该值为空则直接跳出finally block.
所以在使用using语句时要在using语句中初始化变量。正确的代码如下:
using (RegistryKey typeNameKey = Registry.ClassesRoot.CreateSubKey(".ABCD")) {
    typeNameKey.SetValue("", "Test");
}
同时注意在using block要避免改变using语句中所使用的变量的值。

 

  2004年4月19日 6:27

Details at http://blog.joycode.com/gangp/archive/2004/04/19/19852.aspx

相关文章推荐

F4 help functionality for a dynpro screen field using the PROCESS ON VALUE-REQUEST statement

Pressing the F4 button on a dynpro screen field brings up a list of possible values you can enter in...

yum 安装mysql5.7 是 出现无法登陆问题以及mysql error You must reset your password using ALTER USER statement befor

centos7 mysql5.7.17 error You must reset your password using ALTER USER statement before executing t...

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this st

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this st...

[MSSQL]SQL Server 2008 Using the MERGE statement

‘MERGE’ statement is a new feature in SQL Server 2008. It can be used to perform insert, update and ...

Where is also about time A location-distortion model to improve reverse geocoding using behavior-dr

文章:Where is also about time: A location-distortion model to improve reverse geocoding using behavior...

Using XPCOM in JavaScript withoutleaking(about FF)

====================================================== 注:本文源代码点此下载 =============================...

More about using regular expression in notepad++

/*by Jiangong SUN*/ I've written a blog in introducing regular expressions in notepad++, but it's k...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)