2

I am using some XmlReader and XmlWriter object to do some needed work on strings inside some try...catch blocks.

I know that using the notation using (XmlReader NewReader = XmlReader.Create(...)) is the prefered syntax, but I don't really like that so I am also appending finally blocks and executing NewReader.Close(); and NewWriter.Close();.

However, code analysis is complaining that these objects aren't being disposed, thus forcing me to somehow call Dispose() method.

The problem is that in these classes the Dispose() method is implemented explicitly, so I have to use ((IDisposable)(NewReader)).Dispose(); and ((IDisposable)(NewWriter)).Dispose();.

Are there any drawbacks to this technique?

Moon
  • 33,439
  • 20
  • 81
  • 132
User
  • 3,244
  • 8
  • 27
  • 48
  • 7
    Why wouldn't you want to use the using statement. It does everything you need to do, you won't get the fxcop warning *and* it's more concise than using try-finally. – s1mm0t Jul 02 '11 at 13:16

3 Answers3

4

There are good reasons for not using using:

  • When the lifetime of the object might need to survive longer than the current block

and there are poor reasons for avoiding using:

  • "I don't really like that"

Does the good reason apply to your code?

Please also note that a simple extension method would make the syntax nice and clean again.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

The using statement is really the preferred solution. It's idiomatic in C#. These classes implement IDisposable explicitly because they already provide a method that has closing semantics: Close. My bet is that Dispose calls Close, or vice-versa. But you shouldn't count on that, and should always call Dispose anyway.

In the end, all these are equivalent:

  1. Use using, which is preferred;
  2. Call Close on the finally block, and suppress the static analysis warnings or;
  3. Call Dispose on the finally: ((IDisposable)NewReader).Dispose();
Jordão
  • 55,340
  • 13
  • 112
  • 144
  • Unfortunately, `Close` and `Dispose` do not always behave the same. Besides the obvious difference that closed instances can often be reopened, while disposed instances can’t, some objects don't suppress finalization when calling `Close` (such as the `SqlConnection`) which forces you to call `Dispose` anyway to prevent extra pressure on the GC. – Steven Jul 02 '11 at 17:01
1

The C# using statement will always call Dispose for you. It roughtly translates to the following:

XmlReader NewReader = XmlReader.Create(...);
try
{
   // do stuff on NewReader 
}
finally
{
    ((IDisposable)NewReader).Dispose();
}

So wrapping it in finally youself doesn't add any value. Although Close and Dispose are often equivalent, it is not always the case. Because of this FxCop is right, you should always call Dispose and when you do this (or let the using statement do this), there is no reason to call Close manually.

Steven
  • 166,672
  • 24
  • 332
  • 435