Block usage aliases in C #

I have a question about the following code:

DisposableObject holdon = null;

using (DisposableObject o = new DisposableObject())
{
    Console.WriteLine("Inside using block");
    holdon = o;
}

holdon.Method();

      

When I ran this code, I expected to get an exception in line holdon.Method()

, but to my surprise, it happily called Method()

without any problem. I was able to confirm what gets DisposableObject.Dispose()

called on o

when hitting the end of a use block. The question is that I had no luck finding an answer on MSDN. After using the block, it holdon

definitely still points to a valid object in memory, even though it was called Dispose()

. So is holdon

it still pointing to the same object it was previously pointing to o

, or is it pointing to a copy o

?

+3


source to share


2 answers


The disposal object is not associated with the removal of the object from memory. It only means calling a method Dispose()

on that object. All further actions depend on the IDisposable

implementation of the object that you placed. In some cases, the object is set to the "disposed" state, and all further actions raise an exception ( ObjectDisposedException

). But you can do (or not) do anything with the implementation IDisposable

.

eg. this is a completely valid implementation IDisposable

( fiddle ):

public class CrazyDisposable : IDisposable
{
    public int Counter { get; private set; }
    public void Dispose() => Counter++;
}

      




Further reading: using statement (C # Reference) .

And especially the part that explains why it is better to limit the scope of a disposable to a block using

:

You can instantiate a resource object and then pass the variable to use the statement, but this is not best practice. In this case, the object remains in scope after control leaves the block of use even though it probably will no longer have access to its unmanaged resources. In other words, it will no longer be fully initialized. If you try to use an object outside of the used block, you run the risk of throwing an exception. For this reason, it is generally best to instantiate the object in a using statement and limit its scope to the using block.

as you can see it is allowed, but you risk accessing the located object.

+9


source


operator is using

just shorthand for

DisposableObject holdon = null;

{ //This "{" is here to limit the scope of "o"

    DisposableObject o = new DisposableObject()
    try
    {
        Console.WriteLine("Inside using block");
        holdon = o;
    }
    finally
    {
        if(o != null)
        o.Dispose();
    }

}

holdon.Method();

      

So if you call



o.Dispose();
o.Method();

      

in normal code does not throw an exception, and calling holdon.Method()

after o.Dispose()

also does not throw an exception.

+2


source







All Articles