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

Which statement is true about loading data using the conventional path of SQL*Loader? A.Redo is not

Which statement istrue about loading data using the conventional path of SQL*Loader? A.Redo is notg...
  • EVISWANG
  • EVISWANG
  • 2016年01月24日 11:52
  • 818

97.Which statement is true about loading data using the conventional path of SQL*Loader?

97.Which statement is true about loading data using the conventional path of SQL*Loader?
  • dwj19830118
  • dwj19830118
  • 2016年07月28日 17:10
  • 726

OCP-1Z0-053-V12.02-295题

295.Which statement about using RMAN stored scripts is true? A. To create and execute an RMAN stored...
  • rlhua
  • rlhua
  • 2013年10月28日 00:14
  • 4891

53 Which statement about using RMAN stored scripts is true? A. To create and execute an RMA

QUESTION 53 Which statement about using RMAN stored scripts is true? A. To create and execute an R...
  • EVISWANG
  • EVISWANG
  • 2015年11月26日 10:47
  • 336

OCP-V13-697

Which statement is true about a Scheduler-generated event? 下面那个描述正确 关于调度生成事件? A. It can be generate...
  • xuejiayue1105
  • xuejiayue1105
  • 2015年09月21日 14:00
  • 1713

OCP-1Z0-053-200题-145题-295

QUESTION 145 Which statement about using RMAN stored scripts is true? A. To create and execute an ...
  • rlhua
  • rlhua
  • 2014年02月07日 19:48
  • 3268

55 Which statement about recovering from the loss of a redo log group is true? A. If the lost redo l

55 Which statement about recovering from the loss of a redo log group is true? A. If the lost redo...
  • EVISWANG
  • EVISWANG
  • 2015年11月26日 10:53
  • 654

OCP-1Z0-052-V8.02-76题

76. Which statement is true about a whole consistent database backup on a database running in ARCHI...
  • rlhua
  • rlhua
  • 2013年10月12日 16:33
  • 10324

OCP-1Z0-053-V12.02-49题

49.Which statement about recovering from the loss of a redo log group is true? A. If the lost redo l...
  • rlhua
  • rlhua
  • 2013年11月03日 11:03
  • 7516

76.Which statement is true about a whole consistent database backup on a database running in ARCHIVE

76.Which statement is true about a whole consistent database backup on a database running in ARCHIVE...
  • dwj19830118
  • dwj19830118
  • 2016年07月26日 21:30
  • 667
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:A confusing fact about using statement
举报原因:
原因补充:

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