Is nesting dispose necessary?

Asked

Viewed 87 times

4

I have the following hypothetical code.

using (var QDR = new DAL.teste())
{
   //codigos
   using (var QDR1 = new DAL.teste1())
   {
      //codigos
      using (var QDR2 = new DAL.teste2())
      {
            // códigos
      }
   }
 }

The above code is valid however it would be necessary to place all objects inside the using? since in the first using it would not release all variables in memory?

1 answer

4


The Dispose() does not release variables, it frees resources.

Objects in memory (not to be confused with resources) are only released by Garbage Collector at a time when it’s up to him. Variables "are released" when the object containing it is released, or if it is local it is at the time it terminates its scope. Learn more about scope and time and life.

Each using will call the Dispose() only of the resource he created, nothing else. So it is necessary, but can do simply.

Depending on the use it is possible to simplify this code by placing everything in a single block, in this case just do:

using (var QDR = new DAL.teste())
using (var QDR1 = new DAL.teste1())
using (var QDR2 = new DAL.teste2()) {
    // etc
}

I changed my class (MemoryStream) just to make it easier and I had the IL generated just to get a sense of what this does:

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance void M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 61 (0x3d)
        .maxstack 1
        .locals init (
            [0] class [mscorlib]System.IO.MemoryStream,
            [1] class [mscorlib]System.IO.MemoryStream,
            [2] class [mscorlib]System.IO.MemoryStream
        )

        IL_0000: nop
        IL_0001: newobj instance void [mscorlib]System.IO.MemoryStream::.ctor()
        IL_0006: stloc.0
        IL_0007: newobj instance void [mscorlib]System.IO.MemoryStream::.ctor()
        IL_000c: stloc.1
        IL_000d: newobj instance void [mscorlib]System.IO.MemoryStream::.ctor()
        IL_0012: stloc.2
        IL_0013: nop
        IL_0014: nop
        IL_0015: leave.s IL_0022
        IL_0017: ldloc.2
        IL_0018: brfalse.s IL_0021
        IL_001a: ldloc.2
        IL_001b: callvirt instance void [mscorlib]System.IDisposable::Dispose()
        IL_0020: nop
        IL_0021: endfinally
        IL_0022: leave.s IL_002f
        IL_0024: ldloc.1
        IL_0025: brfalse.s IL_002e
        IL_0027: ldloc.1
        IL_0028: callvirt instance void [mscorlib]System.IDisposable::Dispose()
        IL_002d: nop
        IL_002e: endfinally
        IL_002f: leave.s IL_003c
        IL_0031: ldloc.0
        IL_0032: brfalse.s IL_003b
        IL_0034: ldloc.0
        IL_0035: callvirt instance void [mscorlib]System.IDisposable::Dispose()
        IL_003a: nop
        IL_003b: endfinally
        IL_003c: ret

        Try IL_0013-IL_0017 Finally IL_0017-IL_0022
        Try IL_000d-IL_0024 Finally IL_0024-IL_002f
        Try IL_0007-IL_0031 Finally IL_0031-IL_003c
    } // end of method C::M

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x20c4
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: ret
    } // end of method C::.ctor

} // end of class C

Even in C# 8 this is not even necessary, the block has become optional (you can still use it if necessary or think it looks better, I think it does not, but who got used to it...):

using var QDR = new DAL.teste();
using var QDR1 = new DAL.teste1();
using var QDR2 = new DAL.teste2();

I put in the Github for future reference.

The block in which these three variables were declared will determine the end and where the release of the resource will take place.

  • in case my code would not give to group, but still worth a using for each? it would not release the resources already in the first using? since he is within him?

  • I don’t see why I couldn’t, but I can’t just talk through this. I can only repeat what is already in the answer, each releases only the resource he created, nothing else. There is this of being inside.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.