In my company, I am seeing code like this
using (LoggerFactory.GetTracer(_log.ModuleName + "._GetAccessTokenFromWns"))
{...}
When I looked up, I learned it disposes the objects referred by variables declared inside "Using" parenthesis.
Does it also help for code like above, where there is no variable referring to the object returned by the factory?
Thanks,
After I see your question I write a simple code like this:
using (new FileStream("sample.txt",FileMode.CreateNew))
{
}
And then I look at the produced IL code
:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 35 (0x23)
.maxstack 2
.locals init ([0] class [mscorlib]System.IO.FileStream CS$3$0000,
[1] bool CS$4$0001)
IL_0000: nop
IL_0001: ldstr "asdas.txt"
IL_0006: ldc.i4.1
IL_0007: newobj instance void [mscorlib]System.IO.FileStream::.ctor(string,
valuetype [mscorlib]System.IO.FileMode)
IL_000c: stloc.0
.try
{
IL_000d: nop
IL_000e: nop
IL_000f: leave.s IL_0021
} // end .try
finally
{
IL_0011: ldloc.0
IL_0012: ldnull
IL_0013: ceq
IL_0015: stloc.1
IL_0016: ldloc.1
IL_0017: brtrue.s IL_0020
IL_0019: ldloc.0
IL_001a: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_001f: nop
IL_0020: endfinally
} // end handler
IL_0021: nop
IL_0022: ret
} // end of method Program::Main
As you can see it is still calling the Dispose
method.It creates FileStream
instance before try
block, then calling the Dispose
method in the finally
.I think this is another advantage of using
statements.
"Disposal" of an object involves cleaning up any resources it may have initialized for its own use. The important task isn't cleaning up a reference, it is clearing file locks, mutexes, etc.
This is the only way of ensuring the disposal of an object without introducing a variable for it. This is the same as
var __invisible = LoggerFactory.GetTracer(_log.ModuleName + "._GetAccessTokenFromWns");
try {
} finally {
__invisible.Dispose();
}
but without the __invisible
variable.
This construct is especially valuable in situations when you do not need a variable, because readers who are familiar with this idiom will find such code more readable.
I believe it still has the same effect. If GetTracer
is returning an instance of a class which implements IDisposable
then this code is ensuring that instance is properly disposed of. Just because there is no assignment of the return value doesn't mean a resource which requires disposal wasn't allocated. The tracer for example could be opening a file and without the using
statement that file lock/ streamreader or whatever resource my go indisposed.