开发者

When to use the Using statement

开发者 https://www.devze.com 2023-02-18 04:57 出处:网络
I think I may be using the Using statement wrong here. What would be a better way of writing this? Dim x As New Serialization.XmlSerializer( ... )

I think I may be using the Using statement wrong here. What would be a better way of writing this?

Dim x As New Serialization.XmlSerializer( ... )
Using file As New FileStream(myFile, FileMode.Create)
   Using writer As XmlWriter = XmlTextWriter.Create(file)
      x.Serialize(writer, myCollection)
   End Using
End Using

I've read that you're only supposed to use a using blo开发者_C百科ck on objects that have a .Dispose() (i.e. implements IDisposable), which is why I'm thinking there shouldn't be a Using on "writer", but instead a writer.Close() at the end. But "file" has both a .Dispose() and a .Close(), so which do I use? The using or file.Close()?

Note: I'm using an XmlWriter because I can customize the output. I removed the settings here, though.


Both FileStream and XmlWriter implement IDisposable - the code is correct. Actually the compiler probably wouldn't let you do this if it was wrong. If there isn't a public .Dispose(), then it must be using explicit interface implementation - but that doesn't change your responsibility for calling .Dispose(). For interest, in C# you can avoid the ever-increasing nesting/indenting, i.e.

using(...a...)
using(...b...)
using(...c...)
{
   ...
}

but fundamentally your current code is correct.


This is indeed confusing and has been the subject of much debate. This is the implementation of the Dispose() method:

Public Sub Dispose()
    Me.Close
End Sub

In other words, calling Dispose() does the exact same thing as calling Close(). You definitely want to take advantage of the Using statement here.


Yes, the .Close and .Dispose issue is a bit unfortunate.

It is (was?) an official MS guideline though. The Close method is called a Domain Specific Alias.

And like the word Alias suggests, you may assume that they do exactly the same. Usually Close will just call Dispose.

The Using ... End Using block will only compile with a reference that is IDisposable (has .Dispose)


General advice:

  • When a Class has a .Dispose, use aUsing block
  • Using is just short-hand for Try ... Finally and you can fall back on that. But
  • Don't get creative trying to combine or economize multiple blocks
  • When the nesting gets to deep (> 3..5), factor out an extra method.


Your code looks correct. Note that you will get a compile-time error if you attempt to use using on a data type that does not support IDispose.


I'd tend to do both, but that could be because I'm a bit old fashioned. If I've opened a file (which you have), I'll explicitly close it. Whether or not the Dispose method does a clean close is up to the implementation of the object, not up to the client. But, as the object still implements IDisposable you still need to call it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号