In C#, using
statement is used to dispose in a deterministic manner the resources without waiting for garbage collector. For example, it may be used to:
-
Dispose SQL commands or connections,
-
Close streams, freeing the underlying source like a file,
-
Free GDI+ elements,
-
etc.
I noticed that using
is used more and more in cases where there is nothing to dispose, but where it’s just more convenient for the caller to write a using
block rather than two separate commands.
Examples:
-
MiniProfiler, written by Stack Overflow team, uses
using
to denote blocks to profile:using (profiler.Step("Name goes here")) { this.DoSomethingUseful(i - 1); }
One alternative approach would be to have two blocks:
var p = profiler.Start("Name goes here"); this.DoSomethingUseful(i - 1); profiler.Stop(p);
Another approach would be to use actions:
profiler.Step("Name goes here", () => this.DoSomethingUseful(i - 1));
-
ASP.NET MVC also picked
using
for forms:<% using (Html.BeginForm()) { %> <label for="firstName">Name:</label> <%= Html.TextBox("name")%> <input type="submit" value="Save" /> <% } %>
Is such usage appropriate? How to justify it, given that there are several drawbacks:
-
Beginners would be lost, since such usage doesn’t correspond to the one which is explained in books and language specification,
-
The code should be expressive. Here, the expressiveness suffers, since the appropriate usage of
using
is to show that behind, there is a resource, like a stream, a network connection or a database which should be released without waiting the garbage collector.
10
Your last statement – that “the appropriate usage of using is to show that behind, there is a resource, like a stream, a network connection or a database which should be released without waiting the garbage collector” is incorrect, and the reason why is given at the documentation for the IDisposable interface: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
The primary use of this interface is to release unmanaged resources.
So, if your class uses any unmanaged resouces, it doesn’t matter when you may or may not want GC to happen – it’s got nothing whatsoever to do with GC as unmanaged resources aren’t GC’ed (https://stackoverflow.com/questions/3607213/what-is-meant-by-managed-vs-unmanaged-resources-in-net).
So the purpose of “using” is not to avoid waiting on GC, it’s to force a release of those unmanaged resources now, before the class instance goes out of scope and it’s Finalize is called. This is important for reasons that should be obvious – an unmanaged resource may have dependencies on other unmanaged resources, and if they are disposed of (or finalized) in the wrong order Bad Things may happen.
So if the class being instanced in the using block uses any unmanaged resources, then then answer is yes – it is appropriate.
Note that IDisposable is not prescriptive about it being only for releasing unmanaged resources, however – just that this is it’s primary purpose. It may be the case that the author of the class has some action that they want to enforce happening at a certain time, and implementing IDisposable may be a way of getting that to happen, but whether or not that’s an elegant solution is something that can only be answered on a case-by-case basis.
Whichever, the use of “using” implies that the class implements IDisposable, so it doesn’t violate code expressiveness; it makes it quite clear what’s going on, in fact.
4
The use of using
implies the presence of a Dispose()
method. Other programmers will assume that such a method exists on the object. Consequently, if an object is not disposable, you should not use using
on it.
Code clarity is king. Either omit the using
, or implement IDisposable
on the object.
MiniProfiler appears to be using using
as a mechanism to “fence in” the code being profiled. There is some merit to this; presumably, MiniProfiler is either calling Dispose()
to stop a timer, or the timer is stopped when the MiniProfiler object goes out of scope.
More generally, you would invokeusing
when some sort of finalization needs to occur automatically. The documentation for html.BeginForm
states that, when the method is used in a using
statement, it renders the closing </form>
tag at the end of the using
block.
That doesn’t necessarily mean it’s still not abuse.
9
using
is error and exception safe. It ensures Dispose()
will be called irregardless of any mistakes the programmer makes. It does not interfere with the catching or handling of exceptions, but the Dispose()
method is executed recursively up the stack when an exception is thrown.
Objects that implement IDispose
but have nothing to dispose when they are done. Are at best, future proofing their design. So that you don’t have to refactor your source code, when in the future, they then need to dispose of something.