Try/Finally block vs calling dispose?

rolls picture rolls · Dec 20, 2013 · Viewed 13k times · Source

Is there any difference between these two code samples and if not, why does using exist?

StreamWriter writer;
try {
    writer = new StreamWriter(...)
    writer.blahblah();

} finally {
    writer.Dispose();
}

vs:

using (Streamwriter writer = new Streamwriter(...)) {
    writer.blahblah
}

I mean in the second example you really should be putting it in a try block anyway so adding the finally block really doesn't use much more effort. I get that the entire thing might be encompassed in a bigger try block but yeah, just seems superfluous to me.

Answer

Dmitry Bychenko picture Dmitry Bychenko · Dec 20, 2013

There're some issues with your code. Never write like this (put using instead), and that's why:

StreamWriter writer;
try {
    // What if you failed here to create StreamWriter? 
    // E.g. you haven't got permissions, the path is wrong etc. 
    // In this case "writer" will point to trash and
    // The "finally" section will be executed
    writer = new StreamWriter(...) 
    writer.blahblah();
} finally {
    // If you failed to execute the StreamWriter's constructor
    // "writer" points to trash and you'll probably crash with Access Violation
    // Moreover, this Access Violation will be an unstable error!
    writer.Dispose(); 
}

When you put "using" like that

  using (StreamWriter writer = new StreamWriter(...)) {
    writer.blahblah();
  }

It's equal to the code

StreamWriter writer = null; // <- pay attention to the assignment

try {
  writer = new StreamWriter(...) 
  writer.blahblah();
}
finally {
  if (!Object.ReferenceEquals(null, writer)) // <- ... And to the check
    writer.Dispose();
}